Recommended for learning unity scripts: index on the unity3d Official Website
The source of this case is the project source code in the digital tutors video tutorial.
Download the project at: FPs of Unity source code
We recommend that you use unityremote for mobile game development. You can run the project on an android machine directly, provided that the driver of the android machine must be installed.
Unityremote: unityremote download
Let's talk about the project requirements. after the project is completed, it will probably implement a task's shooting operation and collision detection to achieve the cremation display after hitting an object.
The key source code is roughly the following JS files. You can download the project files and then compare them.
The basic model is not much to mention. You can understand it directly by looking at the project. The key part is the analysis of several source codes.
Let's briefly introduce the four JS scripts in this case.
Playerweapons is used to control the player's weapons. assaultrifle and shotgun are the specific scripts of the two weapons, which involve specific settings of different shooting frequencies due to different weapons. Damagecontroller is the specific control of damage.
First read the first script playerweapons:
//This script is going to provide base functionality of any weapon we createfunction Awake(){// Select the first weaponSelectWeapon(1);}function Update (){//Check if the fire button was pressedif(Input.GetButton("Fire1"))BroadcastMessage("Fire");if(Input.GetKeyDown("1")){SelectWeapon(0);}else if(Input.GetKeyDown("2")){SelectWeapon(1);}}function SelectWeapon(index : int){for (var i=0;i<transform.childCount;i++){// Activate the selected weaponif (i == index){transform.GetChild(i).gameObject.SetActiveRecursively(true);}// Deactivate all other weaponselse{transform.GetChild(i).gameObject.SetActiveRecursively(false);}}}
On the hierachy panel, we can see that all kinds of guns are in the weapongo subdirectory:
The script uses the setactiverecursively method to activate or deactivate the weapon.
Use for to traverse all weapons to ensure that only one weapon is active at a time.
After running, you can find that the weapon after pressing 1 is different from the weapon after pressing 2, and the hierachy panel clearly shows the weapon activation status:
Let's look at the next two weapons scripts, which involve the time control of the shooting interval.
Shotgun:
var shotCount : int = 8;//Amount of pellets in a shotgun shellprivate var shotSpread : float;var range = 100.0;var fireRate = 0.05;var force = 10.0;var damage = 5.0;var bulletsPerClip = 15;var clips = 20;var reloadTime = 2.0;private var mainCam : GameObject;private var hitParticles : ParticleEmitter;var muzzleFlash : Renderer;var bulletsLeft : int = 0;private var nextFireTime = 0.0;private var m_LastFrameShot = -1;private var reloading = false;function Start (){mainCam = GameObject.FindWithTag("MainCamera");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;}function Fire(){if (bulletsLeft == 0){return;}// If there is more than one bullet between the last and this frame// Reset the nextFireTimeif (Time.time - fireRate > nextFireTime){nextFireTime = Time.time - Time.deltaTime;}// Keep firing until we used up the fire timewhile( nextFireTime < Time.time && bulletsLeft != 0){for (var i=0; i<shotCount; i++){FireOneBullet();nextFireTime += fireRate;}bulletsLeft--;}// Register that we shot this frame so that the LateUpdate function enabled the muzzleflash rendererm_LastFrameShot = Time.frameCount;enabled = true;// Reload gun in reload Timeif (bulletsLeft == 0){Reload();}}function FireOneBullet () { var layerMask = 1 << 8; // layer 8 is waypointslayerMask = ~layerMask; // so hit everything but layer 8 (invert the mask) var hits : RaycastHit[];var direction = SprayDirection(); hits = Physics.RaycastAll(transform.position, direction, range,layerMask);System.Array.Sort(hits, Comparison); // Did we hit anything?for (var i=0;i
Assultrifle:
var range = 100.0; //This is just a default value to give us a range that our weapon can shootvar fireRate = 1.0; //This is another default value that we can change directly in the editor to change the rate of firevar force = 10.0;//This variable gives us the ability to adjust how much force our weapon has when it shoots somethingvar damage = 10.0;//This allows us to apply damage to enemies if they have hit points that must reach 0 before they actually dievar bulletsPerClip = 15;//This variable gives us flexibility to assign how many bullets go into a clip of a specific weaponvar clips = 10;//This variable gives the ability to have limited ammovar reloadTime = 0.5;//We need to be able to adjust how long it takes to reload our weaponprivate var hitParticles : ParticleEmitter;//We need some visual feedback that our bullets are hitting somethingvar muzzleFlash : Renderer;//We also need to see if it's actually firing, plus it looks coolprivate var bulletsLeft : int = 0;//This variable is going to store how many bullets we have left in our clipprivate var nextFireTime = 0.0; //This is going to regulate our fire rate to use actual time instead of how fast the computer runsprivate var m_LastFrameShot = -1;//This also helps regulate the fire ratefunction Start ()//Start functions run any code as the level starts but does not continue to update{//Get the particle system attached to the AssaultRifleGOhitParticles = GetComponentInChildren(ParticleEmitter);//Keeps particles from emitting all the timeif(hitParticles){hitParticles.emit = false;bulletsLeft = bulletsPerClip;}}function LateUpdate()//LateUpdate functions updates every frame as long as the behaviour is enabled{if(muzzleFlash){//We shot this frame so enable the muzzle flashif(m_LastFrameShot == Time.frameCount){//Enable our muzzle flash and animate it to rotatemuzzleFlash.transform.localRotation = Quaternion.AngleAxis(Random.Range(0, 359), Vector3.forward);muzzleFlash.enabled = true;//Play soundif(audio){if(!audio.isPlaying){audio.Play();audio.loop = true;}}}//We need to disable the muzzle flashelse{muzzleFlash.enabled = false;enabled = false;//Stop soundif(audio){audio.loop = false;}}}}//Can we fire? This function is going to checkfunction Fire (){if(bulletsLeft == 0){return;}//If there is more than one bullet between the last and this frame, reset the nextFireTime//This help regulate the fire rate to actual timeif(Time.time - fireRate > nextFireTime){nextFireTime = Time.time - Time.deltaTime;}//Keep firing until we have used up the fire timewhile(nextFireTime < Time.time && bulletsLeft != 0){FireOneShot();nextFireTime += fireRate;}}//This function tells our weapon how to shootfunction FireOneShot(){//We need to cast a ray out in front of the playervar direction = transform.TransformDirection(Vector3.forward);var hit : RaycastHit;//Check to see if we hit anythingif(Physics.Raycast(transform.position, direction, hit, range)){//Apply force to the rigid body we hitif(hit.rigidbody){hit.rigidbody.AddForceAtPosition(force * direction, hit.point);}//Spawn particles at the point we hit the surfaceif(hitParticles){var newParticles = Instantiate(hitParticles, hit.point, Quaternion.FromToRotation(Vector3.up, hit.normal));hitParticles.transform.position = hit.point;hitParticles.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);hitParticles.Emit();newParticles.GetComponent(ParticleAnimator).autodestruct = true;}//Send damage message to the hit objecthit.collider.SendMessageUpwards("ApplyDamage", damage, SendMessageOptions.DontRequireReceiver);}bulletsLeft --;//We need to tell the LateUpdate function that we shot and that it can enable the muzzle flash and audiom_LastFrameShot = Time.frameCount;enabled = true;//We need to reload automatically if the clip is emptyif(bulletsLeft == 0){Reload();}}function Reload(){//We want the actual reload to wait while the animation playsyield WaitForSeconds(reloadTime);//We need to check if we have a clip to reloadif(clips > 0){clips--;bulletsLeft = bulletsPerClip;}}//We may need to check how many bullets to reload if we have total ammo countfunction GetBulletsLeft(){return bulletsLeft;}
These two scripts are worth learning, such as particle usage, audio playback, time-time control, and information transmission. However, if you have different requirements, I will not explain them slowly, for reference only.
Finally, the damagecontroller:
@script RequireComponent(Rigidbody)var hitPoints = 100.0;//We need to determine the amount of hitPoints an enemy hasvar explosionDelay = 0.0;//This is just in case you want the ticks to delay on their explosionvar explosion : Transform;//This variable allows us to attach an explosion behaviour and the ability to control the enemy as it explodesfunction ApplyDamage(damage : float){//We need to check if the enemy is already deadif(hitPoints <= 0.0){return;}hitPoints -= damage;if(hitPoints <= 0.0){//StartEmittingParticlesvar emitter : ParticleEmitter = GetComponentInChildren(ParticleEmitter);if(emitter)emitter.emit = true;Invoke("DelayedExplosion", explosionDelay);}}function DelayedExplosion (){BroadcastMessage("Detonate");}function Detonate(){Destroy(gameObject);if(explosion){Instantiate (explosion, transform.position, transform.rotation);}var emitter : ParticleEmitter = GetComponentInChildren(ParticleEmitter);if(emitter){emitter.emit = false;emitter.transform.parent = null;}}
This script is directly dragged to the enemy's gameobject, applydamage is called in the weapon script, the sendmessageupwards method will spread the message, the enemy gameobject receives information and performs damage processing.
This is a simple FPS case. The script may not be very useful, but this design idea is still desirable, that is, using a gameobject as the father of the weapon to implement weapon control, use the broadcastmessage method to call functions of other objects.
For more information, see the project source code.