Stealth行动中角色的移动和摄像机的跟随

看了官网的案例真的是学了不少的东西,就像这个角色移动官网使用了四元素来编写角色的转弯。各位大佬原谅我这个小白的无知大笑

先附上我写的代码

发图 

/// <summary>
/// 控制角色的移动类
/// </summary>
public class PlayerMove : MonoBehaviour
{
    public float turnSmoothing = 15f;   // 角色转弯的平滑值
    private float speed = 1;            // 角色前进的速度
    private Animator anim;              // 引用角色的Animator组件


    void Awake()
    {
        anim = GetComponent<Animator>();//获得角色身上的Animator组件
    }


    void Update()
    {
        //使用水平和垂直轴作为输入
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        //角色的位置为我们水平和垂直的按键输入
        gameObject.transform.position += new Vector3(h, 0, v) * Time.deltaTime * speed;
        anim.SetFloat("Speed",Mathf.Abs(h)+Mathf.Abs(v));//设置角色动画状态及中的速度参数过度,为水平和垂直的绝对值和Mathf.Abs(h+v)

        //如果水平和垂直不为0才能旋转,如果不写这个判断会出现转过去之后松开按键此时h=0 v=0,那么角色的旋转也为0也就是角色没有旋转又转回来。
        if (h !=0 || v != 0)
        {
            Rotating(h, v);
        }
    }

    /// <summary>
    /// 控制角色的转弯
    /// </summary>
    /// <param name="horizontal"> 水平</param>
    /// <param name="vertical">垂直</param>
    void Rotating(float horizontal, float vertical)
    {
        //设置玩家要转向的目标方向
        Vector3 targetDirection = new Vector3(horizontal, 0f, vertical);
        //将上面的targetDirection设置为四元素。LookRotation可以使玩家的Z轴转向到朝着targetDirection方向,Y轴向上
        Quaternion targetRotation = Quaternion.LookRotation(targetDirection);
        //使玩家由当前的旋转角度平滑的过渡到目标的旋转角度,turnSmoothing*Time.deltaTime是旋转速度,这里乘上Time.deltaTime是减慢的作用
        Quaternion newRotation = Quaternion.Lerp(transform.rotation, targetRotation, turnSmoothing * Time.deltaTime);
        //将玩家当前的旋转角度设置为我们的新角度
        gameObject.transform.localRotation = newRotation;

    }  
}
大家有什么好的想法可以在下面给我一些指导,谢谢

下面是摄像机跟随人物的移动

public class CameraMove : MonoBehaviour
{
    public GameObject player;     //存储角色
    public float smooth = 1.5f;   //相机平滑移动
    private Vector3 relCameraPos; //摄像机与玩家的相对位置
    private float relCameraPosMag; //相对位置的向量长度
    private Vector3 newPos;       //摄像机移动的新位置
   
   void Awake ()
    {
        relCameraPos = transform.position - player.transform.position;//计算玩家和摄像机之间的距离 相当于A点距离B点相对位置为C求 B点位置=A点+C点
        relCameraPosMag = relCameraPos.magnitude - 0.5f;               //(小一点,因为玩家位置坐标在脚上,之后光线检测可能或接触到地面,所以减去0.5可能碰撞到玩家的腹部)

    }
    void Update()
    {
        Vector3 standarPos = player.transform.position + relCameraPos;               //摄像机的初始位置等于玩家位置加上相对位置
        Vector3 abovePos   = player.transform.position + Vector3.up * relCameraPosMag;//摄像机的俯视位置
        Vector3[] checkPoint = new Vector3[5];                                       //存储摄像机的位置数组
        checkPoint[0] = standarPos;                                                  //设置摄像机初始位置
        checkPoint[1] = Vector3.Lerp(standarPos,abovePos,0.25f);                     //从摄像机的初始位置到角色正上方的位置之间的距离,该点为这段距离25%处的点,从摄像机的初始weihz
        checkPoint[2] = Vector3.Lerp(standarPos,abovePos,0.5f);                      //从摄像机的初始位置到角色正上方的位置之间的距离,该点为这段距离25%处的点,从摄像机的初始位置开始计算
        checkPoint[3] = Vector3.Lerp(standarPos,abovePos,0.75f);                     //从摄像机的初始位置到角色正上方的位置之间的距离,该点为这段距离25%处的点,从摄像机的初始位置开始计算      
        checkPoint[4] = abovePos;                                                    //从摄像机的初始位置到角色正上方的位置之间的距离,该点为这段距离25%处的点,从摄像机的初始位置开始计算
        //依次将我们设置的检测点来检测是否能看到角色,如果某个检测点可以看到角色让摄像机平滑移动带这个监测点
        for (int i = 0; i < checkPoint.Length; i++)
        {
            //如果检测到的是玩家则跳出当前循环
            if (ViewPosCheck(checkPoint[i]))
            {
                break;
            }
        }
        //让摄像机平滑的移动到监测点
        transform.position = Vector3.Lerp(transform.position, newPos, smooth * Time.deltaTime);
        //让摄像机转向角色
        SmoothLookAt();

    }

    /// <summary>
    /// 利用射线检测玩家, 原理就是从摄像机发射一条射线,沿着玩家到监测点的方向,射线长度是相对向量的长度。
    /// </summary>
    bool ViewPosCheck(Vector3 checkPos)
    {
        //使用射线检测摄像机是否能够检测到玩家
        RaycastHit hit;    // 检测位置  摄像机指向玩家的相对位置                  相对向量长度
        if (Physics.Raycast(checkPos,player.transform.position-checkPos,out hit,relCameraPosMag))
        {
            //如果检测到不是玩家
            if (hit.transform.gameObject!=player) //如果检测到的是不是玩家
            {
                return false;  //返回false
            }
           
        }
        //设置摄像机新位置为该检测点的位置
        newPos = checkPos;
         return true;                   

    }

    /// <summary>
    /// 让摄像机平滑的转向玩家
    /// </summary>
    void SmoothLookAt()
    {
         //从摄像机的位置指向玩家的向量
         Vector3 relPlayerPosition = player.transform.position - transform.position;

        //根据摄像机到玩家的向量创建旋转角度 也就是建立一个旋转,使z轴朝向relPlayerPosition y轴朝向up。
         Quaternion lookAtRotation = Quaternion.LookRotation(relPlayerPosition, Vector3.up); 

         //从摄像机的旋转角度旋转到摄像机指向玩家的旋转位置
         transform.rotation = Quaternion.Lerp(transform.rotation, lookAtRotation, smooth * Time.deltaTime);
    }
}

这是我自己的理解,有好的方法或者错的地方希望大家给我指教,谢谢。

猜你喜欢

转载自blog.csdn.net/GZasplin/article/details/80768879