球面线性插值
Quaternion.Slerp(Quaternion from ,Quaternion to, float t)
四元数旋转有个重要的特性就是:会以到达终止方向的旋转角度为旋转方向
static function Slerp (from : Quaternion, to : Quaternion, t : float) : Quaternion
Description描述
Spherically interpolates from towards to by t.
球形插值,通过t值from向to之间插值。
C#JavaScript
// Interpolates rotation between the rotations
// of from and to.
// (Choose from and to not to be the same as
// the object you attach this script to)
//在from和to之间插值旋转.
//(from和to不能与附加脚本的物体相同)
var from : Transform;
var to : Transform;
var speed = 0.1;
function Update () {
transform.rotation = Quaternion.Slerp (from.rotation, to.rotation, Time.time * speed);
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Character : MonoBehaviour
{
CharacterController cc;
Vector3 pendingVelocity; // 这一帧移动的向量
public float speed = 6;
// Start is called before the first frame update
void Start()
{
cc = GetComponent<CharacterController>();
}
public void Move(float h)
{
pendingVelocity.x = h * speed;
if(Mathf.Abs(h) > 0.1f)
{
//考虑旋转
Quaternion right = Quaternion.LookRotation(Vector3.forward);
Quaternion left = Quaternion.LookRotation(Vector3.back);
if(h > 0)
{
//往右转
transform.rotation = Quaternion.Slerp(transform.rotation,right, 0.05f);
}
else
{
//往左转
transform.rotation = Quaternion.Slerp(transform.rotation, left, 0.05f);
}
}
cc.Move(pendingVelocity * Time.deltaTime);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
Character character;
void Start()
{
character = GetComponent<Character>();
}
// Update is called once per frame
void Update()
{
float h = Input.GetAxis("Horizontal");
character.Move(h);
}
}
动画融合
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Character : MonoBehaviour
{
CharacterController cc;
Animator animator;
Vector3 pendingVelocity; // 这一帧移动的向量
public float speed = 6;
// Start is called before the first frame update
void Start()
{
cc = GetComponent<CharacterController>();
animator = GetComponent<Animator>();
}
public void Move(float h)
{
pendingVelocity.x = h * speed;
if (Mathf.Abs(h) > 0.1f)
{
//考虑旋转
Quaternion right = Quaternion.LookRotation(Vector3.forward);
Quaternion left = Quaternion.LookRotation(Vector3.back);
if (h > 0)
{
//往右转
transform.rotation = Quaternion.Slerp(transform.rotation, right, 0.05f);
}
else
{
//往左转
transform.rotation = Quaternion.Slerp(transform.rotation, left, 0.05f);
}
}
cc.Move(pendingVelocity * Time.deltaTime);
//更新动画
UpdateAnim();
}
void UpdateAnim()
{
animator.SetFloat("Forward", cc.velocity.magnitude / speed);
}
}
人物跳跃&下落
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Character : MonoBehaviour
{
CharacterController cc;
Animator animator;
Vector3 pendingVelocity; // 这一帧移动的向量
public float speed = 6;
public float jumpSpeed = 5;
bool isGround = false;
void Start()
{
cc = GetComponent<CharacterController>();
animator = GetComponent<Animator>();
}
public void Move(float h,bool jump)
{
pendingVelocity.x = h * speed;
if (Mathf.Abs(h) > 0.1f)
{
//考虑旋转
Quaternion right = Quaternion.LookRotation(Vector3.forward);
Quaternion left = Quaternion.LookRotation(Vector3.back);
if (h > 0)
{
//往右转
transform.rotation = Quaternion.Slerp(transform.rotation, right, 0.05f);
}
else
{
//往左转
transform.rotation = Quaternion.Slerp(transform.rotation, left, 0.05f);
}
}
//处理跳跃逻辑
if (jump && isGround)
{
//正常跳跃
pendingVelocity.y = jumpSpeed;
isGround = false;
}
//考虑下落
if (!isGround)
{
pendingVelocity.y += Physics.gravity.y * 2 * Time.deltaTime;
}
else
{
pendingVelocity.y = 0;
}
cc.Move(pendingVelocity * Time.deltaTime);
//更新动画
UpdateAnim();
}
private void FixedUpdate()
{
isGround = false;
Ray ray = new Ray(transform.position + new Vector3(0,0.2f,0),Vector3.down);
RaycastHit hit;
if(Physics.Raycast(ray,out hit, 0.3f, LayerMask.GetMask("Default")))
{
isGround = true;
}
Physics.Raycast(ray, out hit, 0.3f, LayerMask.GetMask("Default","Ground"));
}
void UpdateAnim()
{
animator.SetFloat("Forward", cc.velocity.magnitude / speed);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
Character character;
void Start()
{
character = GetComponent<Character>();
}
// Update is called once per frame
void Update()
{
float h = Input.GetAxis("Horizontal");
bool jump = Input.GetButtonDown("Jump");
character.Move(h,jump);
}
}
空中换动作
Cinemachine摄像机跟随