人物按键脚本
现设置绑定一些按键,让鼠标的旋转控制摄像机,否则键盘控制摄像机,然后通过两个二目运算符得到前后左右的值,然后将其进行平滑移动,当开关关闭的时候,目标值为零,借助椭圆映射法,将二维向量传入其中,移动的距离和移动的方向都可以求出来
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerInput : MonoBehaviour
{
[Header("自定义设置的按键")]
public string keyA;
public string keyB;
public string keyC;
public string keyD;
public string keyE;
public string keyF;
public string keyG;
//上下左右调整摄像机转动
[Header("人物移动的按键")]
public string keyJRight;
public string keyJUp;
public string keyJDown;
public string keyJLeft;
//上下左右调整人物转动
[Header("鼠标转动的按键")]
public string keyUp;
public string keyDown;
public string keyRight;
public string keyLeft;
//摄像机上下转
public float Jup;
//摄像机左右转
public float Jright;
//鼠标转动速度
public float mouseSensitiivity;
//移动的距离
public float Dmag;
//方向
public Vector3 Dvec;
//垂直方向目标的值
public float targetDup;
//水平方向目标的值
public float targetDright;
//上下移动
public float Dup;
//左右移动
public float Dright;
//垂直方向上的速度
public float velocityDup;
//水平方向上的速度
public float velocityDright;
//开局不锁定位移
private bool inputEnabled=true;
//是否跑步
public bool run;
//是否跳
public bool jump;
private void Update()
{
//鼠标旋转控制摄像机
if (Input.GetMouseButton(1))
{
Jup = Input.GetAxis("Mouse Y") * mouseSensitiivity;
Jright = Input.GetAxis("Mouse X") * mouseSensitiivity;
}
//键盘转控制摄像机
else
{
Jup = (Input.GetKey(keyJUp) ? 1.0f : 0) - (Input.GetKey(keyJDown) ? 1.0f : 0);
Jright = (Input.GetKey(keyJRight) ? 1.0f : 0) - (Input.GetKey(keyJLeft) ? 1.0f : 0);
}
//两个二目运算符相运算得到目标的值
targetDup = (Input.GetKey(keyUp) ? 1.0f : 0) - (Input.GetKey(keyDown) ? 1.0f : 0);
targetDright = (Input.GetKey(keyRight) ? 1.0f : 0) - (Input.GetKey(keyLeft) ? 1.0f : 0);
//平滑处理上下的移动
Dup = Mathf.SmoothDamp(Dup, targetDup, ref velocityDup, 0.1f);
//平滑处理左右移动
Dright = Mathf.SmoothDamp(Dright, targetDright, ref velocityDright, 0.1f);
//如果开关关闭
if (inputEnabled==false)
{
//将目标值全部归零
targetDup = 0;
targetDright = 0;
}
//将此二维向量传入椭圆映射方法中
Vector2 tempDAixs = SquareToCircle(new Vector2(Dright, Dup));
//得到两个新的长度
float Dright2 = tempDAixs.x;
float Dup2 = tempDAixs.y;
//移动的距离
Dmag = Mathf.Sqrt(Dright2 * Dright2+ Dup2 * Dup2);
//移动的方向
Dvec = Dright2 * transform.right + Dup2 * transform.forward;
//跑步开关
run = Input.GetKey(keyA);
jump = Input.GetKeyDown(keyB);
}
/// <summary>
/// 椭圆映射法
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
protected Vector2 SquareToCircle(Vector2 input)
{
//设一个二维向量
Vector2 output=Vector2.zero;
//将xy进行椭圆映射运算
output.x = input.x * Mathf.Sqrt(1 - (input.y * input.y) / 2.0f);
output.y = input.y * Mathf.Sqrt(1 - (input.x * input.x) / 2.0f);
return output;
}
}
移动控制脚本
当人物的速度小于0.5时,执行随机动作,然后进行技能的释放,当按技能键并且不在cd中 释放技能,当抬起按键的时候,技能返回cd中,当按下左shift执行动画跑,并且用二目运算符来确定跑了的话就加大速度,判断跳的动画进行选择,人物移动的向量大于0.1时,人物朝向为转向向量,移动的方向向量为前面所算出的向量,进行移动,
站立时候的动作,定义0-3之间当时间大于20时 为num ,否则为-1,然后执行动画,当timer大于27的时候返回零,反之则为timer
using System;
using System.Collections;
using System.Collections.Generic;
using UnityChan;
using UnityEngine;
using UnityEngine.TextCore;
using Random = UnityEngine.Random;
public class ActorController : MonoBehaviour
{
//人物模型
public GameObject model;
//playerinput类
public PlayerInput pi;
//行走速度
public float walkSpeed;
//跑步速度
public float runSpeed;
//动画
private Animator _animator;
//移动的向量
private Vector3 planarVec;
//人物刚体
private Rigidbody rig;
//上跳乘数
public float jumpVelocity;
//翻滚乘数
public float rollVelocity;
//冲量向量
public Vector3 thrustVec;
//相机脚本
public CamController camcon;
//锁死位移
private bool lockPlanar;
//是否能攻击
private bool canAttack;
//轨道方向
private bool trackDirction;
//刚体
public CapsuleCollider col;
[Header("----------摩擦材质------------")]
public PhysicMaterial frictionOne;
public PhysicMaterial frictionZero;
//wait动画时间
private float timer;
//第三段攻击动画位移
private Vector3 deltaPos;
private float lerpTarget;
private float lerpTarget1;
private AudioSource _source;
private HeroProperty _heroProperty;
public CdShow skillShow;
private void Awake()
{
_animator = model.GetComponent<Animator>();
pi = GetComponent<PlayerInput>();
rig = GetComponent<Rigidbody>();
col = GetComponent<CapsuleCollider>();
_source = GetComponent<AudioSource>();
_heroProperty = GameObject.FindWithTag("Property").GetComponent<HeroProperty>();
}
private void Update()
{
timer += Time.deltaTime;
if (rig.velocity.magnitude<0.1f)
{
wait();
}
//skill1
if (Input.GetKeyDown(KeyCode.J))
{
_animator.SetTrigger("attack1");
}
//skill2
if (Input.GetKeyDown(pi.keyC)&&skillShow.cdskill2==false)
{
_animator.SetTrigger("attack2");
}
if (Input.GetKeyUp(pi.keyC))
{
skillShow.cdskill2=true;
}
//skill3
if (Input.GetKeyDown(pi.keyD)&&skillShow.cdskill3==false)
{
_animator.SetTrigger("attack3");
}
if (Input.GetKeyUp(pi.keyD))
{
skillShow.cdskill3=true;
}
//skill4
if (Input.GetKeyDown(pi.keyE)&&skillShow.cdskill4==false)
{
_animator.SetTrigger("attack4");
}
if (Input.GetKeyUp(pi.keyE))
{
skillShow.cdskill4=true;
}
if (Input.GetKey(KeyCode.LeftShift))
{
if (timer>10)
{
if (!_source.isPlaying)
{
_source.Play();
}
timer = 0;
}
}
if (Input.GetKeyUp(KeyCode.LeftShift))
{
_source.Stop();
}
//播放动画 里面用了一个线性插值运算
_animator.SetFloat("forward", pi.Dmag*Mathf.Lerp(_animator.GetFloat("forward"),
pi.run ? 2.0f : 1.0f,0.5f));
if (pi.jump)
{
if (rig.velocity.magnitude<0.5f)
{
_animator.SetBool("jump1",false);
}
else
{
_animator.SetBool("jump1",true);
}
_animator.SetTrigger("jump");
}
//移动的向量大于0.1
if (pi.Dmag>0.1f)
{
//人物的朝向
model.transform.forward = Vector3.Slerp(model.transform.forward, pi.Dvec, 0.3f);
}
//移动的方向向量
planarVec = pi.Dmag * model.transform.forward*walkSpeed*(pi.run?runSpeed:1.0f);
}
private void FixedUpdate()
{
//移动
rig.velocity=new Vector3(planarVec.x,rig.velocity.y,planarVec.z);
//冲量归零
thrustVec=Vector3.zero;
}
//站立动作
private void wait()
{
int num = Random.Range(0, 3);
num = timer > 20 ? num : -1;
_animator.SetInteger("AnimatorNum",num);
timer = timer > 27 ? 0 : timer;
}
}
动画返回的时候清除tigger信号
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FsmClearSignels : StateMachineBehaviour
{
//清除进入前的数据
public string[] clearAtEnter;
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
foreach (var signal in clearAtEnter)
{
//清除
animator.ResetTrigger(signal);
}
}
}
进入动画的时候通知给母件的信息
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FsmOnEnter : StateMachineBehaviour
{
public string[] OnEnterMessages;
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
foreach (var msg in OnEnterMessages)
{
//通知母组件给其信息
animator.gameObject.SendMessageUpwards(msg);
}
}
}
人物属性 开局的时候在面板显示 时刻再update中更新
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
public class HeroProperty : MonoBehaviour
{
public int hp;
public int mp;
public int attack;
public int speed;
public int money;
public Text _texthp;
public Text _textmp;
public Text _textspeed;
public Text _textattack;
public Text _textmoney;
public int allHp = 200;
public int allMp = 100;
public int allNum = 20;
private void Start()
{
_texthp.text = hp.ToString();
_textmp.text = mp.ToString();
_textspeed.text = speed.ToString();
_textattack.text = attack.ToString();
_textmoney.text = money.ToString();
}
private void Update()
{
_texthp.text = allHp.ToString();
_textmp.text = allMp.ToString();
_textspeed.text = speed.ToString();
_textattack.text = attack.ToString();
_textmoney.text = money.ToString();
}
}
人物受伤害,当人物血小于零时,从新回到该场景,当人物触发敌人的刀光,后面的血条跟着前面的血条走,加血的时候前面跟着后面走
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
public class PlayerDamage : MonoBehaviour
{
private SceneAgain _sceneAgain;
private HeroProperty _heroProperty;
public int damage;
public Scrollbar scrollbarHp;
public Scrollbar scrollbarMp;
private Image _imageHp;
private Image _imageMp;
private Text _textCurrentHp;
private Text _textOlderHp;
private Text _textCurrentMp;
private Text _textOlderMp;
private Animator _animator;
public bool onOffHp;
public bool onOffMp;
private void Start()
{
_heroProperty = GameObject.FindWithTag("Property").GetComponent<HeroProperty>();
_animator = transform.GetChild(0).GetComponent<Animator>();
_imageHp = scrollbarHp.transform.GetChild(0).GetChild(0).GetComponent<Image>();
_textCurrentHp = scrollbarHp.transform.GetChild(1).GetComponent<Text>();
_textOlderHp = scrollbarHp.transform.GetChild(2).GetComponent<Text>();
_imageMp = scrollbarMp.transform.GetChild(0).GetChild(0).GetComponent<Image>();
_textCurrentMp = scrollbarMp.transform.GetChild(1).GetComponent<Text>();
_textOlderMp = scrollbarMp.transform.GetChild(2).GetComponent<Text>();
_sceneAgain = GameObject.Find("CanvasScene").transform.GetChild(0).GetChild(5).GetComponent<SceneAgain>();
_textCurrentHp.text = _heroProperty.hp.ToString();
_textCurrentMp.text = _heroProperty.mp.ToString();
_textOlderHp.text = "/" + _heroProperty._texthp.text;
_textOlderMp.text = "/" + _heroProperty._textmp.text;
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("EnemySlash"))
{
_heroProperty.hp -= damage;
onOffHp = false;
_animator.SetTrigger("damage");
}
}
private void Update()
{
if (_heroProperty.hp<0)
{
_animator.SetTrigger("die");
Destroy(gameObject,2);
_sceneAgain.EndScene();
}
if (onOffHp)
{
_imageHp.fillAmount = Mathf.Lerp(_imageHp.fillAmount,
(float) _heroProperty.hp / int.Parse(_heroProperty._texthp.text), Time.deltaTime * 10);
scrollbarHp.size = Mathf.Lerp(scrollbarHp.size, _imageHp.fillAmount, Time.deltaTime * 5);
}
else
{
scrollbarHp.size = Mathf.Lerp(scrollbarHp.size,
(float) _heroProperty.hp / int.Parse(_heroProperty._texthp.text), Time.deltaTime * 10);
_imageHp.fillAmount = Mathf.Lerp(_imageHp.fillAmount,scrollbarHp.size, Time.deltaTime * 5);
}
if (onOffMp)
{
_imageMp.fillAmount = Mathf.Lerp(_imageMp.fillAmount,(float) _heroProperty.mp / int.Parse(_heroProperty._textmp.text), Time.deltaTime * 10);
scrollbarMp.size = Mathf.Lerp(scrollbarMp.size, _imageMp.fillAmount , Time.deltaTime * 5);
}
else
{
scrollbarMp.size = Mathf.Lerp(scrollbarMp.size, (float) _heroProperty.mp / int.Parse(_heroProperty._textmp.text), Time.deltaTime * 10);
_imageMp.fillAmount = Mathf.Lerp(_imageMp.fillAmount, scrollbarMp.size, Time.deltaTime * 5);
}
_textCurrentHp.text = Mathf.RoundToInt(scrollbarHp.size * int.Parse(_heroProperty._texthp.text)).ToString();
_textCurrentMp.text = Mathf.RoundToInt(scrollbarMp.size * int.Parse(_heroProperty._textmp.text)).ToString();
_textOlderHp.text = "/" + _heroProperty._texthp.text;
_textOlderMp.text = "/" + _heroProperty._textmp.text;
}
}
事件函数,写在模型上,执行动画事件
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestEvent : MonoBehaviour
{
private Transform _model;
private HeroProperty _heroProperty;
private CdShow _cdShow;
private void Start()
{
_model = GameObject.FindWithTag("Player").transform.GetChild(0).transform;
_heroProperty = GameObject.FindWithTag("Property").GetComponent<HeroProperty>();
_cdShow = GameObject.Find("CanvasScene").transform.GetChild(0).GetChild(0).GetComponent<CdShow>();
}
public void Audio0(AudioClip audio)
{
AudioSource.PlayClipAtPoint(audio,transform.position);
}
public void Audio1(AudioClip audio)
{
AudioSource.PlayClipAtPoint(audio,transform.position);
}
public void Audio2(AudioClip audio)
{
AudioSource.PlayClipAtPoint(audio,transform.position);
}
public void Audio3(AudioClip audio)
{
AudioSource.PlayClipAtPoint(audio,transform.position);
}
public void Attack21(AudioClip audio)
{
AudioSource.PlayClipAtPoint(audio,transform.position);
}
public void Attack31(AudioClip audio)
{
AudioSource.PlayClipAtPoint(audio,transform.position);
}
public void Attack41(AudioClip audio)
{
AudioSource.PlayClipAtPoint(audio,transform.position);
}
public void Attack1(GameObject _obj)
{
GameObject obj = Instantiate(_obj,
_model.transform.position + _model.forward.normalized,
_obj.transform.rotation);
obj.GetComponent<Rigidbody>().velocity = _model.forward * 0.5f;
Destroy(obj,3f);
}
public void Attack2(GameObject _obj)
{
_heroProperty.mp -= _cdShow.needMp2;
GameObject obj = Instantiate(_obj,
_model.transform.position + _model.forward.normalized + _model.up.normalized,
_obj.transform.rotation,_model);
Destroy(obj,0.5f);
}
public void Attack3(GameObject _obj)
{
_heroProperty.mp -= _cdShow.needMp3;
GameObject obj = Instantiate(_obj, _model.transform.position, _obj.transform.rotation,_model);
Destroy(obj,3f);
}
public void Attack4(GameObject _obj)
{
_heroProperty.mp -= _cdShow.needMp4;
GameObject obj = Instantiate(_obj, _model.transform.position , _model.rotation);
obj.GetComponent<Rigidbody>().velocity = _model.forward*5f;
Destroy(obj,3f);
}
}