- 最后登录
- 2014-10-23
- 注册时间
- 2011-7-19
- 阅读权限
- 90
- 积分
- 81303
- 纳金币
- -1
- 精华
- 11
|
爆炸(Explosions)
你可能已经注意到了,发射的火箭弹发生碰撞时并没有爆炸产生。下面我们来添加爆炸效果。
把标准资源包中粒子文件夹下的Small Explosion拖拽给火箭弹预制的外部变量Explosion
我们仍然需要定义爆炸的行为,脚本Explosion-Simple内容如下:
var explosionRadius = 5.0;
var explosionPower = 10.0;
var explosionDamage = 100.0;
var explosionTime = 1.0;
function Start () {
var explosionPosition = transform.position;
var colliders : Collider[] = Physics.Overlapsphere (explosionPosition,
explosionRadius);
返回球半径内碰撞器数列
for (var hit in colliders) {
if (!hit)
continue;
if (hit.rigidbody)
{
hit.rigidbody.AddExplosionForce(explosionPower,
explosionPosition, explosionRadius, 3.0);
这部分对爆炸半径内的所有刚体属性物体一个向上的作用力
这样会使爆炸效果看上去很棒!
var closestPoint = hit.rigidbody.ClosestPointOnBounds(explosionPosition);
var distance = Vector3.Distance(closestPoint, explosionPosition);
// The hit points we apply fall decrease with distance from the hit point
var hitPoints = 1.0 - Mathf.Clamp01(distance / explosionRadius);
hitPoints *= explosionDamage;
这部分计算爆炸对每个刚体属性物体造成的毁伤程度。并且毁伤程度随着距爆炸中心地距离而减少。
// Tell the rigidbody or any other script attached to the hit object
// how much damage is to be applied!
hit.rigidbody.SendMessageUpwards("ApplyDamage", hitPoints,
SendMessageOptions.DontRequireReceiver);
这部分是对刚体物体传递一个伤害信息。
}
}
// stop emitting ?
if (particleEmitter) {
particleEmitter.emit = true;
yield WaitForSeconds(0.5);
particleEmitter.emit = false;
}
// destroy the explosion
Destroy (gameObject, explosionTime);
}
把脚本Explosion-Simple付给Small Explosion预制体
这个爆炸脚本可以应用在任何需要爆炸效果的游戏中,要得到特定的效果,只需修改下面几个参数即可:
explosionPower:爆炸威力,移动炸点周围物体的力的大小。
explosionDamage:爆炸造成的毁伤点数。
explosionRadius:爆炸效果范围大小。
这个爆炸脚本与先前初级教程中的那个脚本非常类似,主要的区别就是有了毁伤点数这部分内容。通过变量explosionDamage设置基于距离远近的毁伤点数,外部边缘的物体毁伤程度小于爆炸中心位置的物体。
这意味着现在一个爆炸可以对炸点周围的物体造成伤害。后面我们将讨论如何应用毁伤点数。
运行游戏
机枪(Machine Gun)
类似机枪这样的武器,发射速度比火箭筒快,但造成的伤害小。
创建一个空游戏物体,命名为“机枪”。层级栏中,把这个物体拖放设为“武器”的子物体。
把(Object/weapons/machineGun)机枪模型增加到“机枪”空游戏物体中。
把脚本MachineGun赋予“机枪”游戏物体。
在机枪物体参数栏的变量Muzzle Flash栏中把muzzle_flash(机枪的子物体)付给这个变量。
机枪的脚本如下MachineGun:
var range = 100.0;
var fireRate = 0.05;
var force = 10.0;
var damage = 5.0;
var bulletsPerClip = 40;
var clips = 20;
var reloadTime = 0.5;
private var hitParticles : ParticleEmitter;
var muzzleFlash : Renderer;
private var bulletsLeft : int = 0;
private var nextFireTime = 0.0;
private var m_LastFrameShot = -1;
function Start ()
{
hitParticles = GetComponentInChildren(ParticleEmitter);
// We don't want to emit particles all the time, only when we hit something.
if (hitParticles)
hitParticles.emit = false;
bulletsLeft = bulletsPerClip;
}
函数Start其实就是用来初始化粒子发射器的(bullet spark),设定它开始时为关闭状态。
function LateUpdate()
{
if (muzzleFlash)
{
// We shot this frame, enable the muzzle flash
if (m_LastFrameShot == Time.frameCount)
{
muzzleFlash.transform.localRotation =
Quaternion.AngleAxis(Random.Range(0, 359), Vector3.forward);
muzzleFlash.enabled = true;
if (audio)
{
if (!audio.isPlaying)
audio.Play();
audio.loop = true;
}
}
// We didn't, disable the muzzle flash
else
{
muzzleFlash.enabled = false;
enabled = false;
// Play sound
if (audio)
{
audio.loop = false;
}
}
}
}
执行Update函数后,会自动执行LateUpdate函数。注意,Update函数是在脚本PlayWeapons中调用的,这个脚本配置给了Weapons游戏物体(机枪的父物体)。一般而言,当你想某些效果是在Update函数中调用而相应的效果出现在LateUpdate函数中,就使用LateUpdate函数。例如这个例子,判断玩家“是否开火”(if firing)是在Update函数中,在LateUpdate函数中应用火花效果(muzzle flash)。
function Fire ()
{
if (bulletsLeft == 0)
return;
// If there is more than one bullet between the last and this frame
// Reset the nextFireTime
if (Time.time - fireRate > nextFireTime)
nextFireTime = Time.time - Time.deltaTime;
// Keep firing until we used up the fire time
while( nextFireTime < Time.time && bulletsLeft != 0)
{
FireOneShot();
nextFireTime += fireRate;
}
}
Fire函数是基于机枪发射速度来判断玩家是否能开火。
function FireOneShot ()
{
var direction = transform.TransformDirection(Vector3.forward);
var hit : RaycastHit;
// Did we hit anything?
if (Physics.Raycast (transform.position, direction, hit, range))
{
// Apply a force to the rigidbody we hit
if (hit.rigidbody)
hit.rigidbody.AddForceAtPosition(force * direction, hit.point);
// Place the particle system for spawing out of place where we hit the surface!
// And spawn a couple of particles
if (hitParticles)
{
hitParticles.transform.position = hit.point;
hitParticles.transform.rotation =
Quaternion.FromToRotation(Vector3.up, hit.normal);
hitParticles.Emit();
}
// Send a damage message to the hit object
hit.collider.SendMessageUpwards("ApplyDamage", damage,
SendMessageOptions.DontRequireReceiver);
}
bulletsLeft--;
// Register that we shot this frame,
// so that the LateUpdate function enabled the muzzleflash renderer for one frame
m_LastFrameShot = Time.frameCount;
enabled = true;
// Reload gun in reload Time
if (bulletsLeft == 0)
Reload();
}
函数FireOneShot运行时,会在FPS控制器前方发射出一条射线来判断子弹是否击中了什么东西。我们将把子弹的射击距离限定在一定范围内。
如果射线射到某个刚体物体上,就会在那个点上对这个刚体物体产生一定的作用力(因为是机枪,所以作用力很小)。然后在这个点的位置再产生一个火花。粒子发射器方向也会变为沿着这个点的法线方向。
然后,通过对被击中的物体发送一个毁伤信息来对它应用毁伤效果。
function Reload () {
// Wait for reload time first - then add more bullets!
yield WaitForSeconds(reloadTime);
// We have a clip left reload
if (clips > 0)
{
clips--;
bulletsLeft = bulletsPerClip;
}
}
function GetBulletsLeft () {
return bulletsLeft;
}
函数Reload是来装载一个弹夹(还有弹夹的话)。装载时间可以在参数栏中进行调节。
设置粒子发射器(Configuring the particle emitter)
机枪在其子弹与其他刚体物体发生碰撞时应该有个小火花的效果,下面我们来创建它:
从Standard Assets/Particales文件夹下,把Sparks预制拖放到层级栏中,使其成为machineGun的子物体(不是MachineGun)
搞定!运行游戏。不要忘了1和2是切换武器的。
由 lsermao 发表 |
|