M4枪 射击特效
代码:Gun.js
function GenerateGraphicStuff(hit : RaycastHit) { var hitType : HitType; var body : Rigidbody = hit.collider.rigidbody; if(body == null) { if(hit.collider.transform.parent != null) { body = hit.collider.transform.parent.rigidbody; } } if(body != null) { if(body.gameObject.layer != 10 && !body.gameObject.name.ToLower().Contains("door")) { body.isKinematic = false; } if(!body.isKinematic) { var direction : Vector3 = hit.collider.transform.position - weaponTransformReference.position; body.AddForceAtPosition(direction.normalized * pushPower, hit.point, ForceMode.Impulse); } } var go : GameObject; var delta : float = -0.02; var hitUpDir : Vector3 = hit.normal; var hitPoint : Vector3 = hit.point + hit.normal * delta; switch(hit.collider.tag) { case "wood": hitType = HitType.WOOD; go = GameObject.Instantiate(woodParticle, hitPoint, Quaternion.FromToRotation(Vector3.up, hitUpDir)) as GameObject; break; case "metal": hitType = HitType.METAL; go = GameObject.Instantiate(metalParticle, hitPoint, Quaternion.FromToRotation(Vector3.up, hitUpDir)) as GameObject; break; case "car": hitType = HitType.METAL; go = GameObject.Instantiate(metalParticle, hitPoint, Quaternion.FromToRotation(Vector3.up, hitUpDir)) as GameObject; break; case "concrete": hitType = HitType.CONCRETE; go = GameObject.Instantiate(concreteParticle, hitPoint, Quaternion.FromToRotation(Vector3.up, hitUpDir)) as GameObject; break; case "dirt": hitType = HitType.CONCRETE; go = GameObject.Instantiate(sandParticle, hitPoint, Quaternion.FromToRotation(Vector3.up, hitUpDir)) as GameObject; break; case "sand": hitType = HitType.CONCRETE; go = GameObject.Instantiate(sandParticle, hitPoint, Quaternion.FromToRotation(Vector3.up, hitUpDir)) as GameObject; break; case "water": go = GameObject.Instantiate(waterParticle, hitPoint, Quaternion.FromToRotation(Vector3.up, hitUpDir)) as GameObject; break; default: return; } go.layer = hit.collider.gameObject.layer; if(hit.collider.renderer == null) return; if(timerToCreateDecal < 0.0 && hit.collider.tag != "water") { go = GameObject.Instantiate(bulletMark, hit.point, Quaternion.FromToRotation(Vector3.forward, -hit.normal)); var bm : BulletMarks = go.GetComponent("BulletMarks"); bm.GenerateDecal(hitType, hit.collider.gameObject); timerToCreateDecal = 0.02; } }
分析:根据枪射击到不同的材质,实例化不同的特效
子弹打在材质上表面留下的痕迹:
贴花系统,没怎么看明白,Decal System
http://game.ceeger.com/Components/shader-NormalDecal.html
http://docs.unity3d.com/Documentation/ScriptReference/RaycastHit-textureCoord.html
查看BulletMarks.js 重点部分代码:
#pragma strict #pragma implicit #pragma downcast enum HitType { CONCRETE, WOOD, METAL, OLD_METAL, GLASS, GENERIC } class BulletMarks extends MonoBehaviour { public var concrete : Texture2D[]; public var wood : Texture2D[]; public var metal : Texture2D[]; public var oldMetal : Texture2D[]; public var glass : Texture2D[]; public var generic : Texture2D[]; public function GenerateDecal(type : HitType, go : GameObject) { var useTexture : Texture2D; var random : int; switch(type) { case HitType.GENERIC: if(generic == null) return; if(generic.Length == 0) return; random = Random.Range(0, generic.Length); useTexture = generic[random]; break; ....... default: if(wood == null) return; if(wood.Length == 0) return; random = Random.Range(0, wood.Length); useTexture = wood[random]; return; } transform.Rotate(new Vector3(0, 0, Random.Range(-180.0, 180.0))); Decal.dCount++; var d : Decal = gameObject.GetComponent("Decal"); d.affectedObjects = new GameObject[1]; d.affectedObjects[0] = go; d.decalMode = DecalMode.MESH_COLLIDER; d.pushDistance = 0.009 + BulletMarkManager.Add(gameObject); var m : Material = new Material(d.decalMaterial); m.mainTexture = useTexture; d.decalMaterial = m; d.CalculateDecal(); d.transform.parent = go.transform; }