看了官网的案例真的是学了不少的东西,就像这个角色移动官网使用了四元素来编写角色的转弯。各位大佬原谅我这个小白的无知
先附上我写的代码
发图
/// <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);
}
}
这是我自己的理解,有好的方法或者错的地方希望大家给我指教,谢谢。