123 第1页 | 共3 页下一页
返回列表 发新帖
查看: 16015|回复: 25
打印 上一主题 下一主题

[教程] Mecanim教程 - 射击瞄准点与角色动作的结合

[复制链接]

955

主题

164

听众

7万

积分

版主

Rank: 7Rank: 7Rank: 7

纳金币
59338
精华
28

活跃会员 荣誉管理 突出贡献 优秀版主 论坛元老

跳转到指定楼层
楼主
发表于 2013-10-14 03:45:40 |只看该作者 |倒序浏览
pstatus"> 本帖最后由 艾西格亚 于 2013-10-14 03:59 编辑

在前面的教程里面,我们学习到了使用Body Mask功能强化了士兵上半部的动作,使其可以在移动时做出投弹与射击,通过这个部分的学习让我们认识了Mecanim在动画处理上的强大之处。

导读:
五分钟了解Mecanim角色动画系统
http://www.narkii.com/club/thread-305414-1.html

Mecanim动画系统 - 使用Blend Trees控制角色动作
http://www.narkii.com/club/thread-305557-1.html

Mecanim动画系统 - 在角色上使用Mask 叠加动画层
http://www.narkii.com/club/thread-305706-1.html

接下来的教程,我们将要介绍如何在第三人称的角色上面添加更多的控制,需要完成的部分是角色的转向与跳跃,然后在进行瞄准的时候能使角色的上半身跟随做出转动。

下载本教程附件后导入Unity,打开Layers and Masks场景,选择Swat@rifle_jump,这是角色跳跃的动作文件,我们需要对这个文件进行一下设置。

1.jpg

将Animation Type更换为Humanoid模式,Avatar Definition更换为CopyFromOtherAvatar,在Source栏位将SwatAvatar添加进来,按下Apply完成设置。

2.jpg

在Animations的栏位内只勾选Root Transform Rotation > Bake into Pose这个选项,其余的设置保存默认值即可。

3.jpg

打开swatController03动画设置文件,按下Parameters新增三个Bool形态的判断式,分别是Jump、TurnLeft与TurnRight的属性,然后再新增三个State,名称也是Jump、TurnLeft与TurnRight,如图所示:

4.jpg

接下来进行动作的关联设置,如图所示,使用Make Transition方式将Move连接到Jump(双向),Idle分别与Jump、TurnLeft、TurnRight进行连接(双向)。

5.jpg

Transition连接完成后,进行Conditions的设置,Move → Jump、Idle → Jump、Idle → TurnLeft与Idle → TurnRight 皆设置为True, 反向的部分则为False。

6.jpg

设置完成Transition后,将rifle _jump、turn_left与turning_right_45degrees分别添加到Jump、TurnLeft与TurnRight的Motion栏位内。

7.jpg

打开BasicController03的脚本,在 public float transitionTime = 0.25f;后面添加以下的代码:
  1. public float jumpSpeed = 4.0F;
  2. public float gravity = 20.0F;
  3. private float jumpPos = 0.0f;
  4. private float verticalSpeed = 0;
  5. private float xVelocity = 0.0f;
  6. private float zVelocity = 0.0f;
复制代码
然后在(controller.isGrounded){之后加入以下的代码:
  1. if (Input.GetKey(KeyCode.Space)) {
  2.    animator.SetBool("Jump", true);
  3.    verticalSpeed = jumpSpeed;
  4. }else{
  5.    animator.SetBool("Jump", false);
  6. }

  7. if(Input.GetKey(KeyCode.Q)){
  8.    animator.SetBool("TurnLeft", true);
  9.    transform.Rotate(Vector3.up * (Time.deltaTime * -45.0f),
  10.    Space.World);
  11. } else {
  12.    animator.SetBool("TurnLeft", false);
  13. }

  14. if(Input.GetKey(KeyCode.E)){
  15.    animator.SetBool("TurnRight", true);
  16.    transform.Rotate(Vector3.up * (Time.deltaTime * 45.0f), Space.
  17.    World);
  18. } else {
  19.    animator.SetBool("TurnRight", false);
  20. }
复制代码
上面这段代码主要就是设置了按键的执行功能,分别将Q、E与Space键指定到TurnLeft、TurnRight与Jump的动作上,接着在脚本的最后加上一段代码即可:
  1. void OnAnimatorMove(){
  2. Vector3 deltaPosition = animator.deltaPosition;
  3.     if(controller.isGrounded){
  4.     xVelocity = animator.GetFloat("Speed") * controller.
  5.     velocity.x * 0.25f;
  6.     zVelocity = animator.GetFloat("Speed") * controller.
  7.     velocity.z * 0.25f;
  8. }

  9. verticalSpeed += Physics.gravity.y * Time.deltaTime;
  10.     if(verticalSpeed <= 0){
  11.     animator.SetBool("Jump", false);
  12. }

  13. deltaPosition.y = verticalSpeed * Time.deltaTime;
  14.     if(!controller.isGrounded){
  15.     deltaPosition.x = xVelocity * Time.deltaTime;
  16.     deltaPosition.z = zVelocity * Time.deltaTime;
  17. }
  18. controller.Move(deltaPosition);

  19.     if ((controller.collisionFlags & CollisionFlags.Below) !=
  20.     0){
  21.     verticalSpeed = 0;
  22.     }
  23.     transform.rotation = animator.rootRotation;
  24. }
复制代码
上面的代码主要是以OnAnimatorMove这个功能来判断Controller是否碰触到地面所执行的动作,在写入代码后进行效果的测试,角色移动时按下Q与E键可进行左右的转向,按下空白键则是让角色跳跃。

8.jpg
9.jpg

动作测试没问题后,接着我们需要在角色上面增加一个瞄准点的功能,目的是让这个第三人称的角色在进行瞄准目标时,角色的上半身能够跟着做转向,那么要如何来设置呢?

新增一个名称为MouseAim的C#脚本,写入以下的代码:
  1. using UnityEngine;
  2. using System.Collections;

  3. public class MouseAim : MonoBehaviour {

  4.             public Transform spine;
  5.             public Transform armedHand;
  6.             public bool lockY = false;
  7.             public float compensationYAngle = 20.0f;
  8.             public float minAngle = 308.0f;
  9.             public float maxAngle = 31.0f;
  10.             public Texture2D targetAim;
  11.             private Vector2 aimLoc;
  12.             private bool onTarget = false;
  13.        
  14.         public void LateUpdate(){
  15.                     Vector3 point = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.farClipPlane));

  16.                     if(lockY)
  17.                                 point.y = spine.position.y;
  18.                     Vector3 relativePoint = transform.InverseTransformPoint(point.x, point.y, point.z);
  19.                     if(relativePoint.z < 0){
  20.                             Vector3 inverseZ = transform.InverseTransformPoint(relativePoint.x,relativePoint.y,-relativePoint.z);
  21.                                 point = inverseZ;
  22.                     }
  23.                     spine.LookAt(point, Vector3.up);
  24.                     Vector3 comp = spine.localEulerAngles;
  25.                     comp.y = spine.localEulerAngles.y + compensationYAngle;
  26.                     spine.localEulerAngles = comp;
  27.                     if(spine.localEulerAngles.y > maxAngle && spine.localEulerAngles.y < minAngle){
  28.                                 if(Mathf.Abs((spine.localEulerAngles.y - minAngle)) < Mathf.Abs((spine.localEulerAngles.y - maxAngle))){
  29.                                             Vector3 min = spine.localEulerAngles;
  30.                                             min.y = minAngle;
  31.                                             spine.localEulerAngles = min;
  32.                                 } else {
  33.                                             Vector3 max = spine.localEulerAngles;
  34.                                             max.y = maxAngle;
  35.                                             spine.localEulerAngles = max;
  36.                                     }
  37.                     }

  38.                 RaycastHit hit;
  39.                     if(Physics.Raycast(armedHand.position,point, out hit)){
  40.                                 onTarget = true;
  41.                                 aimLoc = Camera.main.WorldToViewportPoint(hit.point);
  42.                     }else{
  43.                                 onTarget = false;
  44.                                 aimLoc = Camera.main.WorldToViewportPoint(point);
  45.                                        
  46.                         }
  47.            }
  48.        
  49.             void OnGUI(){
  50.                     int sw = Screen.width;
  51.                     int sh = Screen.height;
  52.                     GUI.DrawTexture(new Rect(aimLoc.x * sw - 8, sh - (aimLoc.y * sh) -8, 16, 16), targetAim,    ScaleMode.StretchToFill, true, 10.0f);
  53.             }
  54.        
  55. }
复制代码
这段代码主要是将鼠标在屏幕上的位置转换成场景的空间坐标,然后以LookAt()来旋转角色的躯干(上半身),同时必须保持目标点在角色的后方,才能让角色一直保持正确的瞄准点位置。

接着将MouseAim.cs的脚本拖曳到士兵模型,在Inspector里面需要对几个栏位进行设置。

10.jpg

将士兵模型物件里面的Spine添加到MouseAim> Spine,RightHand添加到ArmedHand的栏位,将GUI 目录下的crossAim贴图添加到Target Aim的栏位内。

13.jpg

设置完成后进行测试,现在角色的上半身已经可以跟随鼠标的移动做出转向。

14.jpg

15.jpg

16.jpg

另外我们还可以搭配KGFMapSystem来制作迷你地图,如图所示,右上方黄色的小箭头即为士兵模型在场景中的位置。

17.jpg

KGFMapSystem 2.3 下载位置:
http://www.narkii.com/club/thread-304320-1.html

KGFMapSystem - 快速创建游戏中的迷你地图
http://www.narkii.com/club/thread-289124-1.html

更多的Unity技术交流与分享请加入:纳金网Unity论坛专属交流群 - 218689657

Original_Character_3.zip

4.63 MB, 下载次数: 761

分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏2 支持支持0 反对反对0
回复

使用道具 举报

9903

主题

126

听众

7万

积分

首席设计师

Rank: 8Rank: 8

纳金币
53488
精华
316

最佳新人 热心会员 灌水之王 活跃会员 突出贡献 荣誉管理 论坛元老

沙发
发表于 2013-10-14 08:43:03 |只看该作者
很不错的Macanim应用
回复

使用道具 举报

ku 智囊团   

89

主题

2

听众

5万

积分

首席设计师

Rank: 8Rank: 8

纳金币
25
精华
1

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

板凳
发表于 2013-10-14 08:43:33 |只看该作者
相当不错的教程,希望了视频教程,打上纳金水印
回复

使用道具 举报

2722

主题

42

听众

3万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
38268
精华
111

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

地板
发表于 2013-10-18 20:38:27 |只看该作者
很不错的系列,支持做PDF
回复

使用道具 举报

115

主题

3

听众

5676

积分

高级设计师

Rank: 6Rank: 6

纳金币
7268
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

5#
发表于 2013-10-18 21:10:55 |只看该作者
感覺非常實用~
回复

使用道具 举报

2

主题

1

听众

1143

积分

助理设计师

Rank: 4

纳金币
350
精华
0
6#
发表于 2013-10-28 10:11:25 |只看该作者
感谢楼主分享~
回复

使用道具 举报

ZackD    

715

主题

22

听众

4万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
26224
精华
17

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

7#
发表于 2013-11-14 11:12:53 |只看该作者
很受用,谢谢了
回复

使用道具 举报

0

主题

1

听众

198

积分

设计实习生

Rank: 2

纳金币
7
精华
0

最佳新人

8#
发表于 2013-11-19 16:36:41 |只看该作者
看完了,这教程牛B级了~~~
回复

使用道具 举报

33

主题

1

听众

2680

积分

中级设计师

Rank: 5Rank: 5

纳金币
559
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

9#
发表于 2013-11-19 17:24:20 |只看该作者
相当不错的教程
回复

使用道具 举报

0

主题

1

听众

126

积分

设计实习生

Rank: 2

纳金币
298
精华
0

最佳新人

10#
发表于 2013-11-19 22:29:51 |只看该作者
感谢分享
回复

使用道具 举报

123 第1页 | 共3 页下一页
返回列表 发新帖
您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-11-15 04:29 , Processed in 0.628876 second(s), 33 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部