在Unity3D中开发射击游戏的一些思路(1)

最近有许多朋友问到我一个问题,如何实现像战地,使命召唤那样逼真的射击体验。首先我们要知道,在没有动画师的帮助下,要想实现人为模拟的后坐力,精准度偏移等等其实并不是什么难事,今天我们就来用较简短的代码来实现一个模拟的枪械后坐力。

首先是我们需要用到的工具类代码:

public class Spring3
{
	public Vector3 value = Vector2.zero;
	private Vector3 dampValue = Vector2.zero;
	private float damp = 1;
	private float frequence = 1;
 	public void Clear ()
	{
		value = Vector2.zero;
		dampValue = Vector2.zero;
	}
	public Spring3 (float damp, float frequence)
	{
		this.damp = damp;
		this.frequence = frequence;
	}
	public void Update (float deltaTime, Vector3 target)
	{
		value -= dampValue * deltaTime * frequence;
		dampValue = Vector3.Lerp (dampValue, value - target, deltaTime * damp);
	}
}
	public class SpringEulerAngle
	{
		public Vector3 value = Vector2.zero;
		private Vector3 dampValue = Vector2.zero;
		private float damp;
		private float frequence = 1;


		public SpringEulerAngle (float damp, float frequence)
		{
			this.damp = damp;
			this.frequence = frequence;
		}


		public void Clear ()
		{
			value = Vector2.zero;
			dampValue = Vector2.zero;
		}


		public void Update (float deltaTime, Vector3 target)
		{
			value -= dampValue * deltaTime * frequence;
			dampValue = eulerLerp (dampValue, value - target, deltaTime * damp);
		}


		public static Vector3 eulerLerp(Vector3 left, Vector3 right, float t){
			Vector3 ret;
			ret.x = Mathf.LerpAngle (left.x, right.x, t);
			ret.y = Mathf.LerpAngle (left.y, right.y, t);
			ret.z = Mathf.LerpAngle (left.z, right.z, t);
			return ret;
		}
	}
这是我们在进行模拟时最常用的一个算法,我称之为弹簧算法(实在起不出好名字了嘿嘿),算法非常简单,我们只需要把自己的value输入进去,作为希望插值的目标,然后调用Update函数就可以让value以弹性姿势像target靠拢,需要注意的是damp和frequency这两个浮点数的用处,可以看到damp越高插值速率越高,越快的趋近于目标点,而frequency越高弹簧震动的越快,我们在之后的模拟中会用到这两个值的。

通过使用弹簧算法,我们可以很轻松的实现一个让抬起的枪口归位的动作,那么我们怎么实现一套完整的后坐力弧线呢。要知道我们在开枪的时候(去过射击场的朋友应该知道),枪口是呈现一个类似抛物线的运动,在扣动扳机瞬间枪口迅速上抬,随即在胳膊与胸口的压力下枪的上抬幅度慢慢降低并开始下降,降到开枪前的点,所以我们需要在代码中模拟这一系列动作。

这时有同学就会问了,直接把摄像机或者枪的transform.eulerAngles绑到上边代码中的value不就行了么,这期教程不就可以结束了么,如果这样想我只能说这位同学有些失了智,有灵性的同学应该已经发现了问题,单纯通过一个弹簧,只能模拟枪口归位,但是枪口上抬这个过程就只能强行进行角度偏移,就没法实现我们说过的抛物线效果。所以我们应该用另一个插值来模拟一整套后坐力。将以下脚本挂载到枪或摄像机上,即可触发后坐力。

明白了道理以后,就非常容易实现了,我们这里写一段非常简单的代码,通过点击鼠标左键触发,给目标加一段随机的角度,并且实现一个抛物线性质的偏移,注意,因为后坐力控制属于物理运动,所以应该放在FixedUpdate中执行,FixedUpdate与Update的执行关系这里就不赘述了。

public class Recoil : MonoBehaviour {
	SpringEulerAngle recoilTarget;
	public float damp = 20;
	public float frequence = 15;
	void Awake(){
		recoilTarget = new SpringEulerAngle (damp, frequence);
	}
	
	// Update is called once per frame
	void FixedUpdate () {
		recoilTarget.Update (Time.deltaTime, Vector3.zero);
		transform.rotation = Quaternion.Lerp (transform.rotation, Quaternion.Euler (recoilTarget.value), 0.75f);	//这里使用一个较大的插值数字以实现枪口的迅速抬升
	}

	void Update(){
		if (Input.GetMouseButtonDown (0)) {
			recoilTarget.value = new Vector3 (Random.Range (-20, 0), Random.Range (-3, 3), 0);	//这里做一个随机偏移来模拟后坐力。
		}
	}
}
将这段控制后坐力的代码保存为Recoil.cs并且挂载到摄像机或者模型上,运行点击左键就可以看出效果,只不过要想实现自己理想的后坐力,需要通过不停的调参来获得令自己满意,令策划满意的效果。

  • 10
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值