找回密码
 立即注册
首页 业界区 业界 第三人称——骑马系统以及交互动画

第三人称——骑马系统以及交互动画

暴灵珊 14 小时前
骑马系统

人物在马上的脚本
  1. using MalbersAnimations;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. public class ThirdPersonRidingHorse : MonoBehaviour
  6. {
  7.     [Header("骑马参数")]
  8.     public GameObject horse;
  9.     public bool isOnHorse;
  10.     //void OnInteract()
  11.     //{
  12.     //    var thirdPersonMove = GetComponent<ThirdPersonMove>();
  13.     //    thirdPersonMove.enabled = false;
  14.     //    var pos = horse.transform.Find("Pos_UpToHorse");
  15.     //}
  16.     CharacterController characterController;
  17.     Animator animator;
  18.     ThirdPersonMove thirdPersonMove;
  19.     private void Awake()
  20.     {
  21.         characterController = GetComponent<CharacterController>();
  22.         animator = GetComponent();
  23.         thirdPersonMove = GetComponent<ThirdPersonMove>();
  24.     }
  25.     private void Update()
  26.     {
  27.         if (isOnHorse)
  28.         {
  29.             var axisX = Input.GetAxis("Horizontal");
  30.             var axisY = Input.GetAxis("Vertical");
  31.             animator.SetFloat("AxisX", axisX);
  32.             animator.SetFloat("AxisY", axisY);
  33.         }
  34.         Ride();
  35.     }
  36.     void Ride()
  37.     {
  38.         //上马
  39.         if (!isOnHorse)
  40.         {
  41.             if (Input.GetKeyDown(KeyCode.F))
  42.             {
  43.                 isOnHorse = true;
  44.                 transform.rotation = horse.transform.rotation;
  45.                 transform.position = horse.transform.position;
  46.                 //将角色放到马上
  47.                 var playerPoint = horse.transform.Find("PlayerPoint");
  48.                 transform.SetParent(playerPoint);
  49.                 transform.localPosition = Vector3.zero;
  50.                 //在马上禁用角色的characterController和move
  51.                 characterController.enabled = false;
  52.                 thirdPersonMove.enabled = false;
  53.                 //开启马的输入控制脚本
  54.                 horse.GetComponent<MalbersInput>().enabled = true;
  55.                 //切换马上动作状态,即权重从0到1
  56.                 animator.SetLayerWeight(2, 1f);
  57.             }
  58.         }
  59.         //下马
  60.         else
  61.         {
  62.             if (Input.GetKeyDown(KeyCode.F))
  63.             {
  64.                 isOnHorse = false;
  65.                 if (horse != null)
  66.                 {
  67.                     //删除马之前设置角色位置
  68.                     transform.SetParent(null);
  69.                     transform.position = horse.transform.position;
  70.                     transform.rotation = horse.transform.rotation;
  71.                     //下马后恢复角色的characterController和move
  72.                     characterController.enabled = true;
  73.                     thirdPersonMove.enabled = true;
  74.                     //关闭马的输入控制脚本
  75.                     horse.GetComponent<MalbersInput>().enabled = false;
  76.                     //关闭马上动作层
  77.                     animator.SetLayerWeight(2, 0f);
  78.                 }
  79.             }
  80.         }
  81.     }
  82. }
复制代码
马的部分——插件:Horse Animset Pro Riding System 4.0.1.unitypackage

1.png

状态机设置

先学习怎么做场景交互

以常见的开宝箱交互为例:
1)先建一个可开盖宝箱的模型
2.png

3.png

2)在Box的子级中建立一个空的GameObject,当作角色开始播放交互动画的位置
4.png

3)在Box的animation窗口中建立动画——Box的开盖动画
5.png

6.gif

4)这里需要把开盖动画的Loop Time给取消勾选
7.png

5)来到Timeline窗口,新建一个Box的Timeline,把Box的开盖动画和角色交互的动画拖进去
8.png

注:角色动画是mixamo里找的
9.png

角色的Track在k帧的时候选上 角色的animator,在k完之后就记得要取消勾选animator
10.png

也要记得修改该动画的名字,后面脚本会用到
11.png

为了保证开盖动画在人物动画播完后仍然还在播,点开开盖动画的Animation Track,设置为continue
12.png

6)把人物移到和PlayerStandPosition同一个位置,追求完美可以k一下开盖动画和角色动画的匹配度,并加上过渡动画(这里我就懒得弄了,因为只是学习怎么做动画交互系统)
7)为Box加上Tag-Box
13.png

8)为Box加上Trigger碰撞体
14.png

9)取消勾选Play On Awake,不然还没触发就开始播动画了
15.png

16.png

OK,交互动画匹配好了,下面写脚本控制角色到达一个Box周围的Trigger碰撞体区域,按下交互的Input按键才触发动画
脚本逻辑:
在碰撞体区域按下按键->开始找tag为Box的GameObject,找到的对象就是Box->在Box的子级中找名为PlayerStandPosition的对象->更新角色位置、朝向->在Box的playerableAsset中找到PlayerTrack,播放相应的BoxTimeline
脚本如下:
PlayerOpenBox.cs
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.Playables;
  5. using UnityEngine.InputSystem;
  6. public class PlayerOpenBox : MonoBehaviour
  7. {
  8.     bool isPlaying = false;
  9.     IEnumerator OnInteract()
  10.     {
  11.         if (list.Count > 0 && isPlaying == false)
  12.         {
  13.             isPlaying = true;
  14.             var thirdPersonMove = GetComponent<ThirdPersonMove>();
  15.             thirdPersonMove.enabled = false;
  16.             var thirdPersonJump = GetComponent<ThirdPersonJump>();
  17.             thirdPersonJump.enabled = false;
  18.             var thirdPersonRoll = GetComponent<ThirdPersonRoll>();
  19.             thirdPersonRoll.enabled = false;
  20.             var director = list[0];
  21.             list.RemoveAt(0);
  22.             var pos = director.transform.Find("PlayerStandPosition");
  23.             transform.position = pos.position;
  24.             //Debug.Log(pos.position);
  25.             transform.rotation = pos.rotation;
  26.             var animator = GetComponent();
  27.             foreach (var output in director.playableAsset.outputs)
  28.             {
  29.                 if (output.streamName == "PlayerTrack")
  30.                 {
  31.                     director.SetGenericBinding(output.sourceObject, animator);
  32.                     break;
  33.                 }
  34.             }
  35.             director.Play();
  36.             while(director.state == PlayState.Playing)
  37.             {
  38.                 yield return null;
  39.             }
  40.             thirdPersonMove.enabled = true;
  41.             thirdPersonJump.enabled = true;
  42.             thirdPersonRoll.enabled = true;
  43.             isPlaying = false;
  44.         }
  45.     }
  46.   
  47.     List<PlayableDirector> list = new List<PlayableDirector>();
  48.     private void OnTriggerEnter(Collider other)
  49.     {
  50.         if (other.gameObject.tag == "Box")
  51.         {
  52.             var director = other.gameObject.GetComponent<PlayableDirector>();
  53.             if (director != null && !list.Contains(director))
  54.             {
  55.                 list.Add(director);
  56.             }
  57.             //Debug.Log(transform.position);
  58.         }
  59.     }
  60.   
  61.     private void OnTriggerExit(Collider other)
  62.     {
  63.         if (other.gameObject.tag == "Box")
  64.         {
  65.             var director = other.gameObject.GetComponent<PlayableDirector>();
  66.             if (director != null && list.Contains(director))
  67.             {
  68.                 list.Remove(director);
  69.             }
  70.         }
  71.     }
  72.   
  73. }
复制代码
脚本挂在角色身上
效果如下:
17.gif

上下马交互系统


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册