Unity3D游戏开发从零单排(六) - 人物运动及攻击连击
提要
今天要实现的是一个简单人物控制器。
包括用w,a,s,d来控制人物上下左右跑动,鼠标左击发出连招,都是基于老的lagacy的动画。尽管unity3d自带有charactorcontroller,可是并非非常好用,所以人物控制相关的所有自己来实现。先上效果图:
场景搭建
首先下载这个package,里面包括了人物的动作还有地面的模型。
将人物和地面都拖进场景中。这里的模型默认的动画模式是lagacy,不用改动。模型有点偏小,改变模型的scale值为10.最好不要改源文件的scale的scale factor。可能会出现骨骼错位的问题。
接下来给摄像机加入一个天空盒组件,加入一个unity自带的天空盒就好。
对于人物还要加入几个component:
加入Rigdbody来控制人物,选择IsKinematic,这样角色就不会被外力影响。加了CapsuleCollider让角色 不掉下去。
HeroController用来控制角色的运动和打斗。以下会说。
角色行走
思路非常easy,通过wasd获得行走的方向,然后相应控制角色的位移就能够了,只是在变向的时候要注意角色的平滑转身。
首先定义 一个 枚举变量,为角色可能的状态。
	public enum ActionState
	{
		Attack_1,
		Attack_2,
		Attack_3_1,
		Attack_3_2,
		Attack_3_3,
		Attack_4,
		Fire,
		Jump,
		Run,
		Idle
	}
	private ActionState actionState = ActionState.Idle;
Animate函数来依据角色的状态播放相应的动画
	void Animate()
	{
		float delayTime = -0.1f;
		switch (actionState) {
		case ActionState.Attack_3_1:
			delayTime = -0.1f;
			playerAnimation.CrossFade("Attack3-1", 0.15f);
			currentAnimationClip = playerAnimation["Attack3-1"].clip;
			break;
		case ActionState.Attack_3_2:
			delayTime = -0.1f;
			playerAnimation.CrossFade("Attack3-2", 0.15f);
			currentAnimationClip = playerAnimation["Attack3-2"].clip;
			break;
		case ActionState.Attack_3_3:
			delayTime = -0.1f;
			playerAnimation.CrossFade("Attack3-3", 0.15f);
			currentAnimationClip = playerAnimation["Attack3-3"].clip;
			break;
		case ActionState.Attack_4:
			delayTime = -0.1f;
			playerAnimation.CrossFade("Attack4", 0.15f);
			currentAnimationClip = playerAnimation["Attack4"].clip;
			break;
		case ActionState.Idle:
			playerAnimation.CrossFade("Idle", 0.35f);
			currentAnimationClip = playerAnimation["Idle"].clip;
			break;
		case ActionState.Jump:
			playerAnimation.CrossFade("Jump", 0.15f);
			currentAnimationClip = playerAnimation["Jump"].clip;
			break;
		case ActionState.Run:
			playerAnimation.CrossFade("Run", 0.15f);
			currentAnimationClip = playerAnimation["Run"].clip;
			break;
		case ActionState.Fire:
			playerAnimation.CrossFade("Fire", 0.15f);
			currentAnimationClip = playerAnimation["Fire"].clip;
			break;
		default: break;
		}
		//Switch to default if an animation is almost over
		if (playerAnimation[currentAnimationClip.name].time > (playerAnimation[currentAnimationClip.name].length + delayTime)){
			actionState = ActionState.Idle;
			currentAnimationClip = playerAnimation["Idle"].clip;
		}
	}
在update函数中加入相应的逻辑函数:
	// Update is called once per frame
	void Update () {
		float h = Input.GetAxis("Horizontal");
		float v = Input.GetAxis("Vertical");
		MovementManagement (h, v);
		Animate ();
	}
MovementManagement函数就是依据输入处理角色行走的
	void MovementManagement(float horizontal, float vertical)
	{
		if(horizontal != 0f || vertical != 0f)
		{
			Rotating(horizontal, vertical);
			actionState = ActionState.Run;
			moveDirection = new Vector3(horizontal, 0.0f, vertical);
			rigidbody.MovePosition(rigidbody.position + speed * moveDirection * Time.deltaTime);
		}
	}
平滑转身函数(參考Unity官网的toturial)
void Rotating(float horizontal, float vertival)
	{
		Vector3 targetDirection = new Vector3 (horizontal, 0f, vertival);
		// Create a rotation based on this new vector assuming that up is the global y axis.
		Quaternion targetRotation = Quaternion.LookRotation(targetDirection, Vector3.up);
		// Create a rotation that is an increment closer to the target rotation from the player's rotation.
		Quaternion newRotation = Quaternion.Lerp(rigidbody.rotation, targetRotation, turnSmoothing * Time.deltaTime);
		// Change the players rotation to this new rotation.
		rigidbody.MoveRotation(newRotation);
	}
因为这里是简单的平地,所以处理起来比較简单。当须要控制角色在复杂的地形上行走的时候,比方山川丘陵,就须要角色在Y方变化了。这个时候仅仅须要勾选角色的rigidbody component的 use gravity。然后限制rigidbody的x。z方向的移动了,x,z方向的移动要全然靠脚本来处理。
角色连击
首先来思考一下逻辑。
角色初始值状态是Idle。此时按下攻击。发连招的第一招,假设玩家继续按的话就进入第二招,依次类推,假设中途停下的话,就还是回到Idle状态。这是最简单的单线连招的逻辑,没有考虑打断,多连等情况,代码实现例如以下:
	void AttackLogic()
	{
		if (Input.GetButtonDown ("Fire1"))
		{
			if(actionState != ActionState.Attack_3_1 && actionState != ActionState.Attack_3_2
			   && actionState != ActionState.Attack_3_3&& actionState != ActionState.Attack_4)
			{
				Debug.Log ("Fire");
				actionState = ActionState.Attack_3_1;
			}
			else if(actionState == ActionState.Attack_3_1 && playerAnimation[currentAnimationClip.name].time > 1.0f)
			{
				actionState = ActionState.Attack_3_2;
			}
			else if(actionState == ActionState.Attack_3_2 && playerAnimation[currentAnimationClip.name].time > 1.0f)
			{
				actionState = ActionState.Attack_3_3;
			}
			else if(actionState == ActionState.Attack_3_3 && playerAnimation[currentAnimationClip.name].time > 1.0f)
			{
				actionState = ActionState.Attack_4;
			}
			/*else if(actionState == ActionState.Attack_3 && playerAnimation[currentAnimationClip.name].time > 2.0f)
			{
				actionState = ActionState.Idle;
			}*/
		}
		else if(Input.GetButtonDown ("Jump"))
		{
			actionState = ActionState.Jump;
		}
		else if(Input.GetButtonDown ("Fire2"))
		{
			actionState = ActionState.Fire;
			//if (currentSkill==null)
		}
	}
执行一下,就能够实现最開始的那个效果了。
參考
Unity3d toturial - Stealth
Unity3D游戏开发从零单排(六) - 人物运动及攻击连击的更多相关文章
- Unity3D游戏开发从零单排(四) - 制作一个iOS游戏
		
提要 此篇是一个国外教程的翻译,尽管有点老,可是适合新手入门. 自己去写代码.debug,布置场景,能够收获到非常多.游戏邦上已经有前面两部分的译文,这里翻译的是游戏的最后一个部分. 欢迎回来 在第一 ...
 - Unity3D游戏开发从零单排(五) - 导入CS模型到Unity3D
		
游戏动画基础 Animation组件 Animation组件是对于老的动画系统来说的. 老的动画形同相应的动画就是clip,每一个运动都是一段单独的动画,使用Play()或CrossFade(),直接 ...
 - Unity3D游戏开发从零单排(三) - 极速创建狂拽酷炫的游戏地形
		
提要 在Unity工作流程内,地形是一个必不可少的重要元素.不论是游戏或虚拟现实都会使用到各种类型的地形效果,在这个教学中我们须要了解到地形的制作基本概念与,当中对于Unity的地形操作部分须要大量的 ...
 - Unity3D游戏开发初探—2.初步了解3D模型基础
		
一.什么是3D模型? 1.1 3D模型概述 简而言之,3D模型就是三维的.立体的模型,D是英文Dimensions的缩写. 3D模型也可以说是用3Ds MAX建造的立体模型,包括各种建筑.人物.植被. ...
 - [Unity3D]Unity3D游戏开发之跑酷游戏项目解说
		
大家好,我是秦元培.我參加了CSDN2014博客之星的评选,欢迎大家为我投票,同一时候希望在新的一年里大家能继续支持我的博客. 大家晚上好.我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.c ...
 - [Unity3D]Unity3D游戏开发之怪物AI
		
大家好.欢迎大家关注由我为大家带来的Unity3D游戏开发系列文章,我的博客地址为:http://blog.csdn.net/qinyuanpei. 在上一篇文章中,我们基本上实现了一个 ...
 - 从一点儿不会开始——Unity3D游戏开发学习(一)
		
一些废话 我是一个windows phone.windows 8的忠实粉丝,也是一个开发者,开发数个windows phone应用和两个windows 8应用.对开发游戏一直抱有强烈兴趣和愿望,但奈何 ...
 - Unity3D游戏开发之连续滚动背景
		
Unity3D游戏开发之连续滚动背景 原文 http://blog.csdn.net/qinyuanpei/article/details/22983421 在诸如天天跑酷等2D游戏中,因为游戏须要 ...
 - [Unity3D]Unity3D游戏开发之飞机大战项目解说
		
大家好,我是秦元培,欢迎大家继续关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei. 首先感谢大家对我博客的关注,今天我想和大家分享的是一个飞机大战的项目.这是一个比較综合的 ...
 
随机推荐
- tcpdump抓包(转)
			
Linux 环境下,通常通过 tcpdump 来进行抓包和分析.它是几乎所有 Linux 发行版本预装的数据包抓取和分析工具. tcpdump 工具的获取和安装可以参阅相应操作系统的官方文档,本文不再 ...
 - Service(1)
			
服务是一个应用组件,能够在后运行耗时的操作,不提供一个用户界面.(由于不提供界面,所以能够耗时运行,和活动最大的不同).还有一个应用组件能够启动一个服务,服务会继续在后台运行及时用户切换到还有一个应用 ...
 - 我的 Android 学习笔记-Okhttp 的使用(译)
			
okhttp 已经是非常流行的网络请求库了.网上介绍的文章非常之多,但感觉都不是特别系统.遂想到官方应该有介绍的文档,仔细寻找一番,果然.但可惜是英文的,于是就大致翻译了一下,权当做笔记了. 1.Ca ...
 - Android中Intent传递类对象的方法一(Serializable)
			
Activity之间通过Intent传递值,支持基本数据类型和String对象及它们的数组对象byte.byte[].char.char[].boolean.boolean[].short.short ...
 - Editing a Book UVA - 11212 IDA*
			
You have n equal-length paragraphs numbered 1 to n . Now you want to arrange them in the order of 1 ...
 - ftp 下载最近一小时的文件
			
#!/bin/bash #cd /home/ftptmp/ ftp -v -n 192.168.0.100 2121 <<EOF user test 2009 binary cd OU ...
 - Java基础07 包(转载)
			
包(package)的目的就是为了更好的组织Java程序. 包的建立 包的建立非常简单.我们只用在Java程序的开始加入package就可以了.我们以Human类为例,将它放入包中: packag ...
 - Linux 文件管理(C语言库函数一)
			
系统调用函数能够直接操作系统设备,C语言库函数是对系统调用函数的封装,增加了可移植性, C语言库函数可以在各个系统上运行,而系统调用则会因为系统不同而有一定的差别. 在读写文件这个操作上,系统函数每次 ...
 - httpclient 怎么带上登录成功后返回的cookie值访问下一页面
			
我是只很菜很菜的小鸟.刚上班,有这个一个需求.要我抓取别的网站的数据. 我根据用户密码登录一个网站成功后,生成一个cookie值.我已经获取到了.然后要带上这个cookie值进行下一页面的访问 ...
 - PHP  规划(收藏的一些好博文)
			
2014-10-15 01:30 36870人阅读 评论(34) 收藏 举报 分类: PHP/DHTML/Other(237) 版权声明:本文为博主原创文章,未经博主允许不得转载. PHP程序员的技术 ...