教程来自B站大佬:https://www.bilibili.com/video/BV1DT4y1A7DJ?spm_id_from=333.337.search-card.all.click&vd_source=19df42746a97e8a5f29ac78388f521d5
在这里主要有2点感悟:
1.对于混合树了解更深刻了
2.人物向量转换关系
3.协程的使用
让子物体的旋转角度与相机旋转角度一致
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FacingCarmera : MonoBehaviour
{
Transform[] childs;
// Start is called before the first frame update
void Start()
{
childs = new Transform[transform.childCount];
for (int i = 0; i < transform.childCount; i++)
{
childs[i] = transform.GetChild(i);
}
}
// Update is called once per frame
void Update()
{
for(int i = 0; i < childs.Length; i++)
{
childs[i].rotation = Camera.main.transform.rotation;//让节点上的子物体与相机旋转角一致
}
}
}
视角转动脚本
using System.Collections;
using System.Collections.Generic;
using SK.Framework;
using UnityEngine;
public class RotateCarmera: MonoBehaviour
{
public float rotateTime = 0.2f;//旋转所花费时间
private Transform player;
private bool isRotating = false;
void Start()
{
player = GameObject.FindGameObjectWithTag("Player").transform;
}
// Update is called once per frame
void Update()
{
transform.position = player.position;
Rotate();
}
void Rotate()
{
if (Input.GetKeyDown(KeyCode.Q) ||Input.GetKeyDown(XBox.LB) && !isRotating)
{
StartCoroutine(RotateAround(-45, rotateTime));
}
if (Input.GetKeyDown(KeyCode.E)|| Input.GetKeyDown(XBox.RB) && !isRotating)
{
StartCoroutine(RotateAround(45, rotateTime));
}
}
//使用协程函数来更新镜头旋转角度
IEnumerator RotateAround(float angel,float time)
{
float number = 60 * time;
float nextAngel = angel / number;
isRotating = true;
for(int i = 0; i < number; i++)
{
transform.Rotate(new Vector3(0, 0, nextAngel));
yield return new WaitForFixedUpdate();//暂停执行 等到下一帧时继续执行下个循环
//默认FixedUpdate()一秒更新60帧
//使用其他频率 修改number前帧数 例如100 这里使用waitforseconds(0.01f)
}
isRotating = false;
}
}
手柄摇杆对照脚本
using UnityEngine;
namespace SK.Framework
{
///
/// XBox按键
///
public class XBox
{
///
/// 左侧摇杆水平轴
/// X axis
///
public const string LeftStickHorizontal = "LeftStickHorizontal";
///
/// 左侧摇杆垂直轴
/// Y axis
///
public const string LeftStickVertical = "LeftStickVertical";
///
/// 右侧摇杆水平轴
/// 4th axis
///
public const string RightStickHorizontal = "RightStickHorizontal";
///
/// 右侧摇杆垂直轴
/// 5th axis
///
public const string RightStickVertical = "RightStickVertical";
///
/// 十字方向盘水平轴
/// 6th axis
///
public const string DPadHorizontal = "DPadHorizontal";
///
/// 十字方向盘垂直轴
/// 7th axis
///
public const string DPadVertical = "DPadVertical";
///
/// LT
/// 9th axis
///
public const string LT = "LT";
///
/// RT
/// 10th axis
///
public const string RT = "RT";
///
/// 左侧摇杆按键
/// joystick button 8
///
public const KeyCode LeftStick = KeyCode.JoystickButton8;
///
/// 右侧摇杆按键
/// joystick button 9
///
public const KeyCode RightStick = KeyCode.JoystickButton9;
///
/// A键
/// joystick button 0
///
public const KeyCode A = KeyCode.JoystickButton0;
///
/// B键
/// joystick button 1
///
public const KeyCode B = KeyCode.JoystickButton1;
///
/// X键
/// joystick button 2
///
public const KeyCode X = KeyCode.JoystickButton2;
///
/// Y键
/// joystick button 3
///
public const KeyCode Y = KeyCode.JoystickButton3;
///
/// LB键
/// joystick button 4
///
public const KeyCode LB = KeyCode.JoystickButton4;
///
/// RB键
/// joystick button 5
///
public const KeyCode RB = KeyCode.JoystickButton5;
///
/// View视图键
/// joystick button 6
///
public const KeyCode View = KeyCode.JoystickButton6;
///
/// Menu菜单键
/// joystick button 7
///
public const KeyCode Menu = KeyCode.JoystickButton7;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public float speed;
new private Rigidbody2D rigidbody;
private Animator animator;
private float inputX, inputY;
//private Vector3 offset;
void Start()
{
// offset = Camera.main.transform.position - transform.position;
rigidbody = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
inputX = Input.GetAxisRaw("Horizontal");
inputY = Input.GetAxisRaw("Vertical");
Vector2 input = (inputX*transform.right + inputY*transform.up).normalized; //标准化到0 1
rigidbody.velocity = input * speed;
if (input != Vector2.zero)
{
animator.SetBool("IsMoving", true);
}
else
{
animator.SetBool("IsMoving", false);
}
animator.SetFloat("InputX", inputX);
animator.SetFloat("InputY", inputY);
// Camera.main.transform.position = transform.position + offset;
}
}
修改 Vector2 input = new Vector2(inputX, inputY).normalized;
到 的解释:
inputX和inputY是基于世界坐标系的参数,如果当自身坐标系和世界坐标系发生偏转时(按下LB或者RB)如下图所示,使用INPUTX 的参数也仅仅会让物体基于世界坐标移动,人物斜着走。
因此需要对人物基于自身坐标进行矫正:
假设人物要向其自身坐标系的Y轴移动
归一化是保证速度不会跟随方向的变化而动态变化,详细见相关文章:为什么要使用Vector2().normalized()