系列文章目录

一 、 人物移动和转向

二、  人物跳跃和落地

三、  人物攻击和判定

四、  人物受伤和死亡

目录

前言

一、人物的站立状态

二、人物的移动实现

1. 添加必要组件

2. Animator状态结构体设置

3. MyPlayerInput脚本实现:

4. MyPlayerController脚本实现:

二、实现转向

根据Axis偏移量实现转向。

然后再update中更新玩家的自身rotation:

总结


前言

本人对游戏的动作系统比较感兴趣,同时打算尽可能系统的学习Unity3d的动作系统,再次记录基于unity案例的学习历程。

实现效果(示例):


提示:以下是本篇文章正文内容,下面案例可供参考

一、人物的站立状态

 不同状态的参数切换:

 在defaultIdle中添加StateMachineBehaviour的派生类

在脚本中实现一定时间后更改整数参数的函数(接口)(创建脚本时会自动生成接口的模板)

    protected float ChangeTime;protected bool idleState = false;protected float idleTime = 0f;protected readonly int hashOfRandomIdle = Animator.StringToHash("RandomIdle");protected readonly int hashOfDefaultIdleState = Animator.StringToHash("DefaultIdleState");//默认idle标签override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex){ChangeTime = Random.Range(5f,8f);idleState = true;animator.SetInteger(hashOfRandomIdle,0);}override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex){idleState = false;}// OnStateMove is called right after Animator.OnAnimatorMove()override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex){idleTime += Time.deltaTime;if(animator.GetCurrentAnimatorStateInfo(0).tagHash == hashOfDefaultIdleState && idleTime >= ChangeTime){idleTime = 0f;int index = Random.Range(1, 4);//Debug.Log("idle:" + index);animator.SetInteger(hashOfRandomIdle, index);//随机赋值 1 到 3}}

OnstateEnter:进入该状态时自动调用,idleTime = 0,idle状态参数设置为0;

OnstateMove:  在Animator.OnAnimatorMove()后调用,对idleTime计时,达到一定时间随机切换idle状态;

默认状态,

随机状态:

二、人物的移动实现

实现人物的向前移动,首先实现的只是向朝向移动,不涉及转向。

1. 添加必要组件

        为人物添加animator、character Controller组件,新建一个MyPlayerInput、MyPlayerController脚本。

        设置人物为Player层级

2. Animator状态结构体设置

Motion混合树:

这里只用1D就行了。在脚本中不断更新forwardSpeed的速度,从而控制人物的前进速度和前进状态(idle、walk、run)。

3. MyPlayerInput脚本实现:

 public class MyPlayerInput : MonoBehaviour{public static MyPlayerInput m_Input{get{return m_Instance;}}protected static MyPlayerInput m_Instance;protected Vector2 m_MoveInput;protected Vector2 m_CameraInput;protected bool m_Jump;protected bool m_attack;[HideInInspector]public bool playerInputBlock;public bool Attack{get{return m_attack && !playerInputBlock;//还要不处于其他状态}}public Vector2 MoveInput{get{return m_MoveInput;}}public Vector2 CameraInput { get {return m_CameraInput;    }}public bool Jump { get {return m_Jump;}}public Coroutine MeleeCoroutine { get; private set; }private void Awake(){Cursor.visible = false;Cursor.lockState = CursorLockMode.Locked;if (m_Instance == null)m_Instance = this;}private void Update(){m_MoveInput.Set(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));m_CameraInput.Set(Input.GetAxis("Mouse X"),Input.GetAxis("Mouse Y"));m_Jump = Input.GetButton("Jump");//按着即触发if(Input.GetButton("Fire1"))//攻击键{if(MeleeCoroutine != null)//现在有个线程(不能进行attack){StopCoroutine(MeleeCoroutine);MeleeCoroutine = null;}MeleeCoroutine = StartCoroutine(StartMelee());//获取线程}if(Input.GetButtonDown("Pause"))//按下瞬间触发{if(Cursor.visible == false){Cursor.visible = true;Cursor.lockState = CursorLockMode.None;}else{Cursor.visible = false;Cursor.lockState = CursorLockMode.Locked;}}}private IEnumerator StartMelee(){m_attack = true;//print(Attack);yield return new WaitForSeconds(0.03f);m_attack = false;}}

脚本获取前后左右偏移量,作为Vecetor2的只读属性传递给PlayerController脚本。

4. MyPlayerController脚本实现:

 protected float m_MaxForwardSpeed{get{if (Input.GetMouseButton(1))//按住鼠标右键可以加速return 8f;else return 4f;}}
//计算前进速度private void CalculateFowardSpeed(){Vector2 moveInput = myInput.MoveInput;if(moveInput.sqrMagnitude > 1){moveInput.Normalize();}float myDesireForwardSpeed = moveInput.magnitude * m_MaxForwardSpeed;//加速度float acceleration = isMoveInput? 13f : 3f;//一直按着前进有不同的加速度效果//v = v0 + at;m_forwardSpeed = Mathf.Lerp(m_forwardSpeed , myDesireForwardSpeed,Time.deltaTime * acceleration);m_animator.SetFloat(hashOfForwardSpeed, m_forwardSpeed);}
private void OnAnimatorMove(){Vector3 movement = Vector3.zero;if(IsGround){//角色中心向脚下发射射线Ray ray = new Ray(m_CharaCtrl.center,-Vector3.up);RaycastHit hitInfo;//根据坡度分解速度if(Physics.Raycast(ray,out hitInfo, k_GroundedRayDistance ,Physics.AllLayers, QueryTriggerInteraction.Ignore)){movement = /*速度在平面方向的投影*/Vector3.ProjectOnPlane(m_animator.deltaPosition/*transform.forward * Time.deltaTime*/,hitInfo.normal);}else{movement = m_animator.deltaPosition;}}else//在空中{movement = m_forwardSpeed * transform.forward * Time.deltaTime;}//向下的速度movement += Vector3.up * m_verticalSpeed * Time.deltaTime;m_CharaCtrl.Move(movement);if (!IsGround)//不在空中时的verticalSpeed没有意义m_animator.SetFloat(hashOfVertialSpeed, m_verticalSpeed);}

一个根据获取的Axis偏移量计算ForwardSpeed,(为了一定的真实性,用v = v0 + at进行速度递增),同时加速度动态变化。

一个根据上面的speed给characterController移动(vertical可以默认一个小的向下速度)

实现效果:

二、实现转向

根据Axis偏移量实现转向。

这个主要要用到四元数。

目标方向: Target  =  new Vector3(moveInput.x,0,moveInput.y);在xz平面的目标方向

cameraDirection :摄像机的正前方(Quaternion)(世界方向)

TargetRotation:cameraDirection 乘 Target,顺序不要反(目标世界方向)

 //计算(玩家)目标的角度private void CalculateRotation(){//目标角度Vector2 mouseInput = new Vector2(myInput.MoveInput.x, myInput.MoveInput.y);//注意这个不是目标方向!!!Vector3 targetDirection = new Vector3(mouseInput.x,0,mouseInput.y);//摄相机的正前方Quaternion CameraForward = Quaternion.Euler(0,m_CameraSetting.Current.m_XAxis.Value,0);//当玩家有输入才计算targetRotationif(!Mathf.Approximately(targetDirection.magnitude,0))m_TargetRotation = Quaternion.LookRotation(CameraForward * targetDirection);//计算偏移角度(增量)Vector3 target = m_TargetRotation * Vector3.forward;float forwardAngle = Mathf.Rad2Deg * Mathf.Atan2(transform.forward.x, transform.forward.z);float targetAngle = Mathf.Rad2Deg * Mathf.Atan2(target.x,target.z);m_DeltatAngle = Mathf.DeltaAngle(forwardAngle,targetAngle);}

然后再update中更新玩家的自身rotation:

//更新玩家的方向private void UpdateQuaternion(){//设置转向角度:m_animator.SetFloat(hashOfDeltaAngle,m_DeltatAngle * Mathf.Deg2Rad);m_TargetRotation = Quaternion.RotateTowards(transform.rotation , m_TargetRotation/*暂时的*/ , turnSpeed);  //转向可以更自然一点transform.rotation = m_TargetRotation;}

总结

本文记录了实现角色的移动和转向,为了使得移动转向更为自然真实,用加速度控制,并且随着时间递增。

笔者感觉难度主要是转向的方向计算、然后是和animation控制器的参数检测。

后续更新角色的跳跃、落地、音效和攻击以及反馈等

Unity-动作系统-案例学习(1)人物移动和转向相关推荐

  1. Unity-动作系统-案例学习(4)人物受伤和死亡

    系列文章目录 一 . 人物移动和转向 二.  人物跳跃和落地 三.  人物攻击和判定 四.  人物受伤和死亡 目录 前言 一.人物受伤逻辑分析 二.人物受伤和死亡动画逻辑 三.人物受伤脚本实现 1.D ...

  2. Unity Dotween官方案例学习

    本文只涉及一些案例,具体查看 DoTween 官方文档. 一. Basics 1 public class Basics : MonoBehaviour 2 { 3 public Transform ...

  3. Unity动画系统学习

    Unity动画系统学习 文章目录 Unity动画系统学习 AnimationState 动画状态 Animation Transitions 动画过渡 动画分层和遮罩 动画混合 1D混合 2D混合 动 ...

  4. Unity 2D案例学习——制作Roguelike随机地下城

    01简介 该学习案例来自b站up主M_Studio的系列视频制作Roguelike随机地下城,此篇博客为案例学习笔记 Notice 1.该项目不包含包括敌人在内的一些游戏元素,仅为具有基础功能的dem ...

  5. unity学习———2D人物的移动

    unity学习---2D人物的移动 代码如下 using System.Collections; using System.Collections.Generic; using UnityEngine ...

  6. 案例学习——Unity基于体绘制的大气散射shader

    本案例学习资料来源 Volumetric Atmospheric Scattering 案例学习--Unity基于体绘制的大气散射shader 0 效果展示 1 引入 1.0 介绍 1.1 单次散射( ...

  7. Unity MVC 案例学习笔记《二》

    MVC 案例学习笔记 注册事件,就是把事件加入到事件字典 发送事件,并携带参数,就是在事件字典中遍历找到具体的 controller 进行处理 using System.Collections; us ...

  8. Unity动画系统详解5:BlendTree混合树是什么?

    摘要:"Animator中有一个功能,用来解决多个动画之间的混合,经常用于移动动画之间的混合,这个功能叫做BlendTree,混合树." 洪流学堂,让你快人几步.你好,我是跟着大智 ...

  9. Unity3D游戏开发案例学习——Tanks!(基本完结)

    [2020.1.12] 概述 本案例来自unity官方中级游戏教程Tanks(单机双人坦克大战) 项目同时用于Unity机器学习内容的学习,预定计划为训练可规避障碍物,欲图消灭玩家的坦克ai 第一部分 ...

最新文章

  1. 3.1、final、finally、 finalize
  2. 科研文献|了解多个含水层中微生物砷的迁移:DNA 和 RNA 分析的见解
  3. 浙二大数据朱继红_快看!浙经贸2020级新生趣味大数据来咯!
  4. c#实现客户端程序自动下载更新(单独程序)
  5. 线程间到底共享了哪些进程资源
  6. 计算机专业论文关于天气预报的,关于天气预报论文范文写作 天气预报相关论文写作资料...
  7. hdu-5707-Combine String
  8. 【ECCV2020】接收论文列表part1
  9. 记录自己的心路文字~
  10. 简单实用的微信缓存框架mmkv
  11. java 获取视频编码_Java如何获取文件编码格式
  12. SPSS学习 相关性分析
  13. python文件操作(1)
  14. android系统怎么取消,安卓系统hd怎么关闭
  15. 早餐吃得好,血管更通畅!4种食物都是不错的选择,远离心血管病
  16. ChannelNets: 省力又讨好的channel-wise卷积,在channel维度进行卷积滑动 | NeurIPS 2018
  17. Share:电脑右下角 今日热文 广告和图标怎么关闭
  18. 墨者WordPress插件漏洞分析溯源
  19. 2023免费版电脑视频剪辑软件会声会影
  20. 【Day34 文献精读】Of magnitudes and metaphors: Explaining cognitive interactions between space, time,and..

热门文章

  1. 浏览器打印多了个空白页
  2. iOS 音频的录制、播放及音频文件管理
  3. android使用airpods软件,安卓怎么使用airpods?安卓上兼容AirPodsPro软件方法教程[多图]...
  4. 【电机驱动与运动控制】考试论述题
  5. 汽车软件开发者的内功心法:V模型
  6. android 计步器
  7. state-of-the-art
  8. 【AUDIO音频兴趣拓展】IOT产品声学结构设计_二、音频器件布局
  9. 华文慕课北大计算机组成原理陆俊林第五章课后习题解析
  10. Android开发:用adb命令安装apk到手机