ダークスピリット刻まフー教師ノート(第一部分の第一四半期)

質問(以下答えます)

1.
Unityの中の文字を介して固定し、実行の間に混合ツリー次元動的切り替え、2つの1次元アニメーションパラメータ、0の前方に固定値を用いて混合することができる、1完全に歩行。
ここに画像を挿入説明

2.
すべての覚醒機能でGetComponent関数は、内部に実現します。

2019年3月17日
3.
FixedUpdateで動作する更新機能必須()関数内に実装することができない(すなわち、剛体文を含む)すべての剛体移動操作、。
60回を行くために1秒の機能を更新し、fixedupdate原則の1秒離れて50回のように、すべてのフレーム間隔が同じではありません:
元である:Time.deltaTime後者は次のとおりです。Time.fixedDeltaTime

4.
次の2つの関数の違いは何ですか?
ここに画像を挿入説明

y成分rigid.velocyそれが0であれば、この場合には、ゲームオブジェクトがジャンプアップしませんし、ダウンはゆっくりと斜面に落下後、空気から直接来てますので、それは、重力の引力がもたらし書き換えます。あなたがrigid.velocityを使用する必要がある場合は、変更rigid.positionは、このような問題ではないであろう、そのような変更をすべきです:

rigid.velocity=new Vector3(movingVec.x,rigid.velocity.y,movingVec.z);

5.
ときにステアリング制御文字は、文字がどのように対処するためにあまりにも速く回しますか?

Slerp Unityが補間のためlerpとしての機能、および関数を使用する必要があり、Slerp球Lerp、球状補間は、この補間方法は、3次元ベクトルに適用可能です。
詳細を参照してください。

https://blog.csdn.net/andyhebear/article/details/51818534

6.
X、Y軸の範囲はプラスまたはマイナス1である場合、X、Y軸が1である場合、1.414斜め速度は1の最大速度を超えるので、円形の範囲内にそれを置く方法を、考慮します?

それは正方形範囲円形の範囲に変換することができる、以下の数式を参照してください。
ここに画像を挿入説明

2019年3月17日
7.
違いInput.GetKeyDownとInput.GetKey二つの機能?

プレスの場合のGetKey関数が真となっているが、唯一の瞬間にダウン真GetKeyDownプレスを返し、長押しにも真を返します。

8.
ユニティデフォルトブール値はfalseです。

9.
トリガーのユニティ倍短命場合、遅延は2幕がトリガされますので、解決策は何ですか?

あなたは、地面に以下のスクリプトを追加し、バックグラウンドにする場合、他のトリガー、OnStateEnter呼び出す前にトリガを削除することができます。

public class FSMClearSignals : StateMachineBehaviour
{
    public string[] clearSignalAtEnter;
    public string[] clearSignalAtExit;
    // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
    //when enters this state(ground),set every trigger to false;
    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        foreach (var signal in clearSignalAtEnter)
        {
            animator.ResetTrigger(signal);
        }
    }

    // OnStateExit is called when a transition ends and the state machine finishes evaluating this state
    override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        foreach (var signal in clearSignalAtExit)
        {
            animator.ResetTrigger(signal);
        }
    }

}

10.
メッセージを呼び出してユニティアニメーターモデルアニメーターのスクリプトは真上機能SubAnimsを呼び出すことができるように、アニメーション内のサブ(これは効率的ではありません)。
:詳細については、次のビデオを参照
https://www.bilibili.com/video/av21513489/?p=15を

2019年3月18日
11
アニメーターアニメーションが終了時間を持っている確認することができます

2019年3月19日
12 Unityの物理エンジンは、以下のように使用される、衝突のすべての一致(衝突)を特定の位置で衝突を作成することができる機能を提供し、その戻り:

     void FixedUpdate(){  
         Collider[]outputCols=Physics.OverlapCapsule(position1,position2,radius);
         if(outputCols.Length!=0)//由于返回的是一串collider,所以要判断是否有碰撞的物体
         print(1111);   //有碰撞的物体则输出
        }

あなたが唯一のコライダーディスプレイの特定の層を指定したい場合は、次のようになります。

 void FixedUpdate()
    {
        Collider[]outputCols=Physics.OverlapCapsule(position1,position2,radius,LayerMask.GetMask("Ground"));
        if (outputCols.Length != 0)
        {
            foreach (var col in outputCols)
            {
                Debug.Log(col.name);
            }
        }
    }

2019年3月20日
13 jumpexitを設定する前に、ジャンプ状態を終了するとき、元の動きベクトルをシャットダウンするためのジャンプランプ後の出会いの問題は、速度の元のレベルを失いました。

2019.3.22
14. trigger类的动画事件需要记得在回到地面的时候初始化trigger的状态。

2019.3.23
15. 关于动画里面的HasExitTime:
勾选:有退出时间,即当前动画要播放完毕后才能跳向下一动画
所以我发现,当动画2和动画3都在动画1后发生,若动画2的优先级高于3,但是如果动画3的transition没有勾选hasExitTime,但是动画2的transition勾选了的话,反而会去做动画3,不做动画2。
不勾选:无退出时间,即只要满足条件即可立即跳转

测试:选择Idle到Run那条线,勾选HasExitTime,在Idle动画刚开始播放时勾选isRun,可以看到要等很久(直到Idle播放完)才会切换到Run;而不勾选HasExitTime则会立即切换

总结:一般不要勾选HasExitTime

2019.3.28
前几天去登山,处理女朋友诈骗,搞寒假作业等花费了不少时间,现在重新开始。
16. 在处理摄像机跟随角色的时候,学到了一个很巧妙的技巧,就是把摄像头上下左右四个方向的旋转,拆分成两个部分,具体层次结构如图:
ここに画像を挿入説明
camera放在两个handle里面,其中playerHandle负责yaw(水平)角,CameraHandle负责pitch(俯仰)角。

17. 还是接着16,出现这个问题,脚本如下:

public class CameraController : MonoBehaviour
{
    public InputPlayer inputP;
    private GameObject playerHandle;
    private GameObject cameraHandle;
    public float horizontalSpeed=20.0f;
    public float verticalSpeed = 50.0f;

    // Start is called before the first frame update
    void Awake()
    {
        cameraHandle = transform.parent.gameObject;
        playerHandle = cameraHandle.transform.parent.gameObject;
    }

    // Update is called once per frame
    void Update()
    {
        playerHandle.transform.Rotate(Vector3.up,horizontalSpeed*inputP.Cright*Time.deltaTime);
        cameraHandle.transform.Rotate(Vector3.right, -verticalSpeed * inputP.Cup * Time.deltaTime);
        cameraHandle.transform.eulerAngles = new Vector3
         (Mathf.Clamp(cameraHandle.transform.eulerAngles.x, -40.0f, 30.0f),
         0,
         0);
    }
}

但是在调整camera的时候,会发现向上移动视角会出现问题,而向下移动视角不会,视频链接如下:
https://www.bilibili.com/video/av21513489/?p=29
说是当角度跨0的时候会出现翻转,出现同位角的概念,总之这应该是与欧拉角的定义有关,具体原因remain。
总之就是,欧拉角在从正数转换为负数的时候,并没有变成负数,所以换成以下方式解决:

public class CameraController : MonoBehaviour
{
    public InputPlayer inputP;
    private GameObject playerHandle;
    private GameObject cameraHandle;
    public float horizontalSpeed=20.0f;
    public float verticalSpeed = 50.0f;
    private float tempX;

    // Start is called before the first frame update
    void Awake()
    {
        cameraHandle = transform.parent.gameObject;
        playerHandle = cameraHandle.transform.parent.gameObject;
        tempX =0f;
    }

    // Update is called once per frame
    void Update()
    {
        playerHandle.transform.Rotate(Vector3.up, horizontalSpeed * inputP.Cright * Time.deltaTime);
        //  cameraHandle.transform.Rotate(Vector3.right, -verticalSpeed * inputP.Cup * Time.deltaTime);
        tempX += -verticalSpeed * inputP.Cup * Time.deltaTime;
        tempX = Mathf.Clamp(tempX, -40.0f, 30.0f);
        cameraHandle.transform.eulerAngles = new Vector3(tempX, cameraHandle.transform.eulerAngles.y, 0);
    }
}

总之得到的结论就是不能直接对欧拉角的值进行clamp,需要使用临时值来替换。

18. Unity中,smoothDamp函数和lerp函数的区别?

首先,二者都是在Vector3下使用,(可能也可以在vector2之类下使用)。
引述:https://www.cnblogs.com/jiahuafu/p/6557915.html

Lerp更像是**线性衰减**,而SmoothDamp像是**弧形衰减**,两者都是由快而慢

其中SmoothDamp多用于相机跟随。但如果其他类型的插值,我个人觉的其实都差不多

SmoothDamp:

transform.position = Vector3.SmoothDamp(transform.position, target.position, ref velocity, smoothTime);
 
Lerp:

transform.position = Vector3.Lerp(transform.position, target.position, 0.1f);

2019.3.29
19. 关于AvatarMask
Avatar是化身的意思,(术语)指在虚拟实境中互动地呈现一个人,比如有电影Avatar(阿凡达)。
AvatarMask的作用,动画遮罩,可以指定人的哪些部位可以播放动画:
ここに画像を挿入説明

20. 报错:
‘ybot’ AnimationEvent ‘ClearSignalAttack’ has no receiver! Are you missing a component?
解决办法:
去找找动画事件里的event,消除event断点。

21. 关于游戏中的trigger组件,常见问题:

  • 如何用代码实现trigger,需要定义两个变量,一个为lastTrigger一个为currentTrigger,
    只有在lastTrigger为0,currentTrigger为1 的时候,启动trigger。

  • 短时间按两下trigger,会重复两次动作,解决办法:在初始动画,比如地面动画上面加脚本(挂在地面上可以方便清除其他trigger),用于在动画做完时清除掉之前的累积trigger,如下:

     using System.Collections;
     using System.Collections.Generic;
     using UnityEngine;
     
     public class FSMClearSignals : StateMachineBehaviour
     {
         public string[] clearSignalAtEnter;
         public string[] clearSignalAtExit;
    
     //when enters this state(ground),set every trigger to false;
     override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
     {
         foreach (var signal in clearSignalAtEnter)
         {
             animator.ResetTrigger(signal);
         }
     }
    
    
     // OnStateExit is called when a transition ends and the state machine finishes evaluating this state
     override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
     {
         foreach (var signal in clearSignalAtExit)
         {
             animator.ResetTrigger(signal);
         }
     }
     }
    
  • 最后别忘了在animator里面设置SetTrigger的值。

22. 在unity的animator里面,没有api可以直接获取当前场景处于哪个动画state中,所以如果想要知道此刻位于哪一个动画状态,需要遍历所有的动画状态。
有函数可以判断特定状态是否为当前状态,实现此功能的函数为:

bool result=animator.GetCurrentAnimatorStateInfo(layerIndex).IsName(stateName);

判断第layerIndex层的名为stateName的状态,若正在此状态则为true。

23. 关于摩擦力,每一个collider上面都可以附加一个摩擦力材质,可以在Assets里面右键添加physics material。所以设置某物体的摩擦力系数,可以把生成的物理材质拖拽进去,也可以在edit–projectsettings----physics里面拖入预设材质。

24. 回顾初中知识:最大静摩擦力近似等于滑动摩擦力,实际上前者要略大一些。

25. 小操作,用于使面板整洁美观

    [Header("=====friction settings=====")]
    public PhysicMaterial frictionOne;
    public PhysicMaterial frictionZero;

效果如图:
ここに画像を挿入説明
稍作改动:

	[Space(10)]
    [Header("=====friction settings=====")]
    public PhysicMaterial frictionOne;
    public PhysicMaterial frictionZero;

如图:
ここに画像を挿入説明
Space函数里面的数字用来调整header与下面变量之间的距离。

26. 游戏bug,当角色跳起来撞到墙时,由于跳跃起来之后锁死了角色的移动,保留了速度,角色会由于摩擦力黏在墙上。
解决办法:当角色离地以后,当进入OnGroundExit时,将角色的collider的摩擦材质设为0,combined设为average,进入OnGroundEnter的时候,材质设为正常。
详情见:https://www.bilibili.com/video/av21513489/?p=36

2019.3.30
27. 动画的种类:
ここに画像を挿入説明

  • legacy 老的动画系统,不推荐使用。
  • Humanoid 人型骨骼动画,通过骨骼映射,去识别别的动画,应用到自己身上。
  • Generic 适用于非人型动画模型。
    参见https://blog.csdn.net/weixin_38239050/article/details/79720472、
    https://blog.csdn.net/sujun10/article/details/53339544
    2019.3.31
    28. 如何实现连击动画,使其不那么简单就能按出来:
    在击打动画中添加event:
    ここに画像を挿入説明
    然后在挂animator的组件下创建脚本,编写ResetTrigger的receiver:
    注意一下:如果想要提高连击按键的难度,应该把事件放在中间,而不是最后。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TriggerController : MonoBehaviour
{
    private Animator anim;
    private void Awake()
    {
        anim = GetComponent<Animator>();
    }
    public void ResetTrigger(string name)
    {
        anim.ResetTrigger(name);
    }
}

2019.4.1
29. unity的动作动画里面有一个镜像系统,如果用右手攻击的动画,勾选镜像功能之后能换成左手攻击:
ここに画像を挿入説明
勾选mirror之后就可以设置为换手攻击,同时mirror组件接受参数调控,不过只接受parameters面板里面的bool型变量。

30. Unity如果想设置手柄参数,设置手柄的button,有这么一个界面,其中positive button和 alt positive button 有何区别,直接设置alt positive button为何会出现一个escape?
ここに画像を挿入説明
alt加上之后和不加alt的设置是一样的效果,是第二按键
很有意思的是,默认加了个escape,我发现测试过程中按手柄的RB键和键盘的ESC键都可以触发结果,两个键效果是一样的。

2019.4.2
31. 公有继承:
基类中所有public成员在派生类中为public属性;
基类中所有protected成员在派生类中为protected属性;
基类中所有private成员在派生类中不可访问
注意继承是不可访问其私有成员,所以如果要访问的话要把其私有成员声明为保护或者共有类型。
protected和public成员的区别:
protected:是指给该类的子类和朋友的,所以protected的访问权限介于private和public之间.

32.
unity,console报错:
GameObject (named ‘MainCamera’) references runtime script in scene file. Fixing!
这是因为之前在GameObject上面添加了类脚本,后来把类定义成了抽象类,所以在inspector上面就看不到了,所以需要把类的abstract去掉,把脚本component移除,再改为抽象类。

33. Unity动画animator下有一条勾选选项:root motion
勾选后,可以实现动画里面的位移,但注意的是,勾选该root motion会只适用于animator挂的物体,不会移动animator挂的物体的父物体,比如playerHandle下面有model,playerHandle上面挂collider,model挂animator,这样勾选以后,collider和model会分开。
所以为了让collider跟上model,需要用函数监听model的移动量,把其赋给playerhandle

对应的函数为:

public class RootMotionController : MonoBehaviour
{
    private Animator anim;
    private void Awake()
    {
        anim = GetComponent<Animator>();
    }
    private void OnAnimatorMove()
    {
        SendMessageUpwards("OnAnimatorRootMotion",anim.deltaPosition);
    }
}

34.
如何让摄像机镜头紧跟角色,一直锁定在人物的颈椎部分。
正好之前为了X、Y轴分离,在人物的颈椎部分有一个cameraHandle,这里可以用到类似OpenGL的LookAt函数()。

35.
出现 bug:unity的camera在开始游戏的时候莫名其妙的看向天空,然后又一阵抖动看向角色。
尝试解决方案,看看camera的层级位置有没有弄错,比如说有没有用LookAt函数出现自己看自己的情况。。。

36.
使用root Motion的时候,相机抖动问题解决办法:
因为rootMotion是要移动刚体的位置,所以属于物理引擎的范畴,但是看看这个东西:
ここに画像を挿入説明
Animator也是一帧帧更新的,它也有animator1.DeltaTime,所以这里的更新模式应该与物理引擎一样,如下图:
ここに画像を挿入説明

36.
函数OnAnimatorIK:
IK的意思是 inverse kinematic 反向动力学。是根据骨骼的终节点来推算其他父节点的位置的一种方法。比如通过手的位置推算手腕、胳膊肘的骨骼的位置。”
OnAnimatorIK() is called by the Animator Component immediately before it updates its internal IK system. This callback can be used to set the positions of the IK goals and their respective weights.
根据我现在所能理解的,就是可以用来调整人物的手等部位的姿势和角度的。
参见:https://www.jianshu.com/p/7aec3699f29c
unity的animator类下有相关操作函数 ,具体的应用示例如下:

public class LeftArmAnimFix : MonoBehaviour
{
    private Animator anim;
    public Vector3 vec3;
    private void Awake()
    {
        anim = GetComponent<Animator>();
    }
    private void OnAnimatorIK()
    {
    	//取得要改变姿态的部位的transform
        Transform LeftLowerArmTransform = anim.GetBoneTransform(HumanBodyBones.LeftLowerArm);
       //设置欧拉角来旋转手臂关节
        LeftLowerArmTransform.localEulerAngles += vec3;
        //改变手臂关节的旋转参数
        anim.SetBoneLocalRotation(HumanBodyBones.LeftLowerArm, Quaternion.Euler(LeftLowerArmTransform.localEulerAngles));
    }
}

2019.4.3
37.
unity加入动画状态时,突然陷入地面的处理方法:
看看添加的动画的rig里面设置的是不是Generic,是的话需要改为Humanoid。

38.
unity获取鼠标输入的方法:用

Input.GetAxis("Mouse X");

39.
Unity如何关闭游标?
参考:https://jingyan.baidu.com/article/b2c186c80cc8b0c46ef6ff80.html
Unity中有Cursor类:

		Cursor.lockState=CursorLockMode.Confined;
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.lockState = CursorLockMode.None;

Cursor有三种锁住的状态:

  • 第一种,把游标限制在当前视角之内,拉不出去,游标仍会显示。
  • 第二种是将游标固定在屏幕的中点并隐藏,按Esc重新显示。
  • 第三种相当于null,也就是不作任何处理的默认状态。

注意:关于游标的操作应该放在camera的相关程序代码里面,这是一个常规的习惯。

2019.4.4
40.
Unity报错:NullReferenceException: Object reference not set to an instance of an object
解决办法:对于自定义类,需要用这样的方式进行实例化:

public className objName=new className();

与原有的C#类不同,原有的类已经分配好了空间,但是对于自定义类需要自己分配内存空间,否则不能使用。

41.
Unity中的按键该有的几个功能:

  • 用来记住按键是否按住的按钮,相当于button功能,按下则为true,不按为false。
  • 用来记住按键触发的按钮,相当于trigger,按下的那一瞬间为true,其他时间为false。
  • 后续还有可能用到的,用来记住按键松手的按钮,松手的一瞬间为true,其他时间为false。
    2019.4.7
  • ダブルクリック機能、ダブルトリガーは、あなたが時間のパッケージを考慮することができるので、あなたは常に内部の更新で現在の時刻を更新することができますが、そのようなことは、別のスクリプトの多くは内部に、非常にお粗末だったアップデートで発生し、それは時間関数を設定する必要があることは明らかですクラス、タイマー。
  • 長押し機能、

しかし、そのような複雑な機能は、生産ボタンを容易にするため、上記の3つの変数が提供され、統一内Buttonクラスを設定する必要はありません。

42.
ダブルトリガーと長押しの機能を達成するのを助けるためにTimerクラスを作成します。

おすすめ

転載: blog.csdn.net/alexhu2010q/article/details/88606298