基于 项目02《游戏-03-开发》Unity3D ,
因前三集资源以及代码冗余问题,本次项目对前三集进行了重做,资源及代码如下,
首先导入场景及人物资源,
为人物添加动画控制器Animator组件,
创建动画控制器文件夹ACs,并在ACs文件夹下创建Animation Controller命名为PlayerAC角色动画控制器,
0层动画控制器:
1层动画控制器:
2层动画控制器:
创建好角色动画控制器后,将PlayerAC绑定在场景中Player的Animator上,
接下来添加新输入系统,
角色移动(包括跳跃,镜头旋转)
角色攻击(包括连击)
绑定MainGame.cs
双击MainGame.cs修改脚本:
using UnityEngine;
public class MainGame : MonoBehaviour{
public static Player player;
void Awake(){
player = GameObject.Find("Player").GetComponent<Player>();
}
}
绑定摄像机跟随代码:
双击CameraCtrl.cs修改脚本:
using UnityEngine;
public class CameraCtrl : MonoBehaviour{
public float dis;
public float height;
public float speed;
Transform target;
Vector3 targetPos;
void Start(){
target = MainGame.player.transform;
}
void Update(){
transform.LookAt(target.position + Vector3.up * 1.5f);
targetPos = target.forward * (-dis) + target.up * height + target.position;
}
void LateUpdate(){
transform.position = Vector3.Lerp(transform.position, targetPos, speed);
}
}
保存代码后回到unity场景设置数值:
创建角色基类Living.cs:
双击Living.cs脚本,
using UnityEngine;
public class Living : MonoBehaviour{
public Animator Anim { get; set; }
protected virtual void InitValue() {
Anim = GetComponent<Animator>();
}
protected void Start(){
InitValue();
}
}
创建角色类Player.cs:
双击Player.cs修改脚本:
using UnityEngine;
using UnityEngine.InputSystem;
public class Player : Living{
float speed = 3;
float rotate;
bool isHoldRotate;//保持旋转角度
void Start(){
base.Start();
SetInput();
contro = GetComponent<CharacterController>();
}
CharacterController contro;
Controls action;
void SetInput(){
action = new Controls();
action.Enable();
action.PlayerCtrl.Move.started += Move;
action.PlayerCtrl.Move.performed += Move;
action.PlayerCtrl.Move.canceled += StopMove;
action.PlayerCtrl.Jump.started += Jump;
action.PlayerCtrl.Rotate.started += Rotate;
action.PlayerCtrl.Rotate.performed += Rotate;
action.PlayerCtrl.HoldRotate.performed += HoldRotate;
action.PlayerCtrl.HoldRotate.canceled += HoldRotate;
action.PlayerAtt.SwordOut.started += SwordOut;
action.PlayerAtt.Att.started += Attack;
}
void Attack(InputAction.CallbackContext obj){
if (Anim.GetCurrentAnimatorStateInfo(0).IsName("Idle_Fight")){
Anim.SetInteger("AttackID", 1);
Anim.SetTrigger("AttackTrigger");
}
else{
int num = Anim.GetInteger("AttackID");
if (num == 6)
return;
if (Anim.GetCurrentAnimatorStateInfo(0).IsName("Attack_" + num))
Anim.SetInteger("AttackID", num + 1);
}
}
void SwordOut(InputAction.CallbackContext obj){
Anim.SetBool("IsSwordOut", !Anim.GetBool("IsSwordOut"));
}
void HoldRotate(InputAction.CallbackContext obj){
if (obj.phase == InputActionPhase.Canceled)
isHoldRotate = false;
else
isHoldRotate = true;
}
void Rotate(InputAction.CallbackContext obj){
rotate = obj.ReadValue<float>();
}
void Jump(InputAction.CallbackContext obj){
Anim.SetTrigger("JumpTrigger");
}
void StopMove(InputAction.CallbackContext obj){
Anim.SetBool("IsRun", false);
}
void Move(InputAction.CallbackContext obj){
Anim.SetBool("IsRun", true);
}
void Ctrl(){
if (Anim.GetCurrentAnimatorStateInfo(0).IsName("Sprint") ||
Anim.GetCurrentAnimatorStateInfo(0).IsName("Run") ||
Anim.GetCurrentAnimatorStateInfo(0).IsName("Idle_ver_A") ||
Anim.GetCurrentAnimatorStateInfo(0).IsName("Idle_Fight")){
float f = action.PlayerCtrl.Move.ReadValue<float>();
contro.Move(transform.forward * f * Time.deltaTime * speed);
contro.Move(transform.up * -9.8f * Time.deltaTime);
if (isHoldRotate)
transform.Rotate(transform.up * rotate * 0.3f);
}
}
void Update(){
Ctrl();
}
}
回到Unity中查看绑定在Player角色身上的脚本Player.cs
添加角色控制器组件,Character Controller
运行项目W/S键执行前后移动,右键控制前进方向,
空闲状态:
战斗状态:按E
鼠标左键连击,
鼠标左键一次,
鼠标左键两次,
鼠标左键三次,
鼠标左键四次,
鼠标左键五次,
战斗状态移动,W/S + 鼠标右键控制视角,
按E,解除战斗状态,
非战斗状态移动,
跳跃,空格键
战斗状态空格键是前滚,
测试完成,
End.