相机控制(Cameramanager)
using UnityEngine;
namespace dgl {
public class CameraManager : MonoBehaviour {
public bool lockon = false;
public float followSpeed = 9;
public float mouseSpeed = 2;
public float controllerSpeed = 7;
public Transform target;
[HideInInspector]
public Transform pivot;
[HideInInspector]
public Transform camTrans;
float turnSmoothing = .1f;
public float minAngle = -35;
public float maxAngle = 35;
float smoothX;
float smoothY;
float smoothXVelocity;
float smoothYVelocity;
public float lookAngle;
public float tilAngle;
public static CameraManager singleton;
public void Init (Transform t) {
target = t;
camTrans = Camera.main.transform;
pivot = camTrans.parent;
}
public void Tick (float d) {
float h = Input.GetAxis ("Mouse X");
float v = Input.GetAxis ("Mouse Y");
float c_h = Input.GetAxis ("RightAxis X");
float c_v = Input.GetAxis ("RightAxis Y");
float targetSpeed = mouseSpeed;
if (c_h != 0 || c_v != 0) {
h = c_h;
v = c_v;
targetSpeed = controllerSpeed;
}
FollowTarget (d);
HandleRotations (d, v, h, targetSpeed);
}
void FollowTarget (float d) {
float speed = d * followSpeed;
Vector3 targetPosition = Vector3.Lerp (transform.position, target.position, speed);
transform.position = targetPosition;
}
void HandleRotations (float d, float v, float h, float targetSpeed) {
if (turnSmoothing > 0) {
smoothX = Mathf.SmoothDamp (smoothX, h, ref smoothXVelocity, turnSmoothing);
smoothY = Mathf.SmoothDamp (smoothY, v, ref smoothYVelocity, turnSmoothing);
} else {
smoothX = h;
smoothY = v;
}
if ( lockon)
{
}
lookAngle+=smoothX*targetSpeed;
transform .rotation=Quaternion.Euler(0,lookAngle,0);
tilAngle -=smoothY*targetSpeed;
tilAngle=Mathf.Clamp(tilAngle,minAngle,maxAngle);
pivot.localRotation=Quaternion.Euler(tilAngle,0,0);
}
/// <summary>
/// Awake is called when the script instance is being loaded.
/// </summary>
void Awake () {
singleton = this;
}
}
}
状态控制(StateManager)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StateManager : MonoBehaviour {
[Header ("Init")]
public GameObject activeModel;
[Header ("Input")]
public float vertical;
public float horiziontal;
public float moveAmount;
public Vector3 moveDir;
[Header ("Stats")]
public float moveSpeed = 2;
public float runSpeed = 3.5f;
public float rotateSpeed = 5;
public float toGround = .5f;
[Header ("States")]
public bool run;
public bool onGround;
public bool lockOn;
[HideInInspector]
public Animator animator;
[HideInInspector]
public Rigidbody rigid;
[HideInInspector]
public float delta;
[HideInInspector]
public LayerMask ignoreLayers;
// Start is called before the first frame update
void Start () {
Init ();
}
// Update is called once per frame
void Update () {
}
public void Init () {
SetupAnimator ();
rigid = GetComponent<Rigidbody> ();
rigid.angularDrag = 999;
rigid.drag = 4;
rigid.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ;
gameObject.layer = 8;
ignoreLayers = ~(1 << 9);
animator.SetBool ("onGround", true);
}
void SetupAnimator () {
if (activeModel == null) {
animator = GetComponent<Animator> ();
if (animator == null) {
Debug.Log ("nO MODEL");
} else {
activeModel = animator.gameObject;
}
}
if (animator == null)
animator = activeModel.GetComponent<Animator> ();
}
public void Tick (float d) {
delta = d;
onGround = OnGround ();
animator.SetBool ("onGround", onGround);
}
void HandleMovementAnimations () {
animator.SetBool ("run", run);
animator.SetFloat ("vertical", moveAmount, .4f, delta);
}
public bool OnGround () {
bool r = false;
Vector3 origin = transform.position + (Vector3.up * toGround);
Vector3 dir = -Vector3.up;
float dis = toGround + .3f;
RaycastHit hit;
if (Physics.Raycast (origin, dir, out hit, dis, ignoreLayers)) {
r = true;
Vector3 targetPosition = hit.point;
transform.position = targetPosition;
}
return r;
}
public void FixedTick (float d) {
delta = d;
rigid.drag = (moveAmount > 0 || onGround == false) ? 0 : 4;
float targetSpeed = moveSpeed;
if (run) {
targetSpeed = runSpeed;
}
if (onGround) {
rigid.velocity = moveDir * (targetSpeed * moveAmount);
}
if (run) {
lockOn = false;
}
if (!lockOn) {
Vector3 targetDir = moveDir;
targetDir.y = 0;
if (targetDir == Vector3.zero) {
targetDir = transform.forward;
}
Quaternion tr = Quaternion.LookRotation (targetDir);
Quaternion targetRotation = Quaternion.Slerp (transform.rotation, tr, delta * moveAmount * rotateSpeed);
transform.rotation = targetRotation;
}
HandleMovementAnimations ();
}
}
输入封装(InputHandler)
using System.Collections;
using System.Collections.Generic;
using dgl;
using UnityEngine;
public class InputHandler : MonoBehaviour {
float vertical = 0;
float horiziontal = 0;
bool runInput;
StateManager states;
CameraManager cameraManager;
float delta;
// Start is called before the first frame update
void Start () {
states = GetComponent<StateManager> ();
states.Init ();
cameraManager = CameraManager.singleton;
cameraManager.Init (this.transform);
}
// Update is called once per frame
void Update () {
delta = Time.deltaTime;
states.Tick (delta);
}
private void FixedUpdate () {
delta = Time.fixedDeltaTime;
GetInput ();
UpdateState ();
states.FixedTick (delta);
cameraManager.Tick (delta);
}
void GetInput () {
vertical = Input.GetAxis ("Vertical");
horiziontal = Input.GetAxis ("Horizontal");
runInput = Input.GetButton ("RunInput");
}
void UpdateState () {
states.vertical = vertical;
states.horiziontal = horiziontal;
Vector3 v = states.vertical * cameraManager.transform.forward;
Vector3 h = states.horiziontal * cameraManager.transform.right;
states.moveDir = (v + h).normalized;
float m = Mathf.Abs (horiziontal) + Mathf.Abs (vertical);
states.moveAmount = Mathf.Clamp01 (m);
if (runInput) {
states.run = (states.moveAmount > 0);
if (states.moveAmount > 0)
states.run = true;
} else {
states.run = false;
}
}
}
//TODO视角锁定 二维混合树动画
版权声明:本文为qmAlin原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。