[Unity3d] DIY tank Fleet Armadatank (2) from the collision
In the previous article I gave a heavy tank fleet and demo program. This article describes the player tank and enemy tank collision problem.
+bit Wei Wei + quietly left a message in this version of the right to say: What kind of collision do we need
In the original, when the player collides with other tanks, the player cannot move with each other, and when the enemy tanks collide with each other, the collision is directly penetrated . The implementation of these features requires some special design.
It should be noted that the tank movement in the tank fleet is in lattice units, and each move will move the entire 1 units . That is, the tank in the D letter shown only the top and bottom of the two stop position, and will not be in the middle of a place to stay.
Accordingly, we give the realization method.
Obstacle Detection method
In the game screen, see the tank is like this:
But in order to achieve the original collision effect, we add to each tank and left and right 4 cubes as an obstacle detector (obstacle Detector), let them detect the location of the tank before and after the presence or absence of obstructions.
To avoid collisions with bullets, we flattened these cubes, with a height of only 0.1 and a length of 1.
In addition, the final purpose of these cubes is to detect the presence of tanks, so give the tank itself a collider.
Note, here we let the enemy tank itself collider radius slightly smaller than 0.5, in order to follow the implementation.
The collider radius of the player's tank remains unchanged by 0.5.
You'll see that this tiny difference makes the collision detection between enemy tanks a little bit dull , so they can penetrate each other, and the enemy tank and the player's tank are still impenetrable.
The role of Cube
The cube works like this: Each cube internally maintains a List<gameobject> obstacles list, this list records all obstructions encountered by this detector. Whenever triggered ontriggerenter(Collider other) ,Other specified objects (obstructions) are addedobstacleslist, whenever triggered ontriggerexit(Collider other) ,Other specified object (obstacle) moved outobstaclesList. In this way, you can analyzeobstaclesDetermine if there are any obstructions in the direction (one or both of the left and right) that this cube represents.
1 Public Abstract classObstacledetector:monobehaviour {2 3 PublicSystem.collections.generic.list<gameobject>obstacles;4 5 voidAwake ()6 {7 if(Obstacles = =NULL)8 {9obstacles =NewSystem.collections.generic.list<gameobject>();Ten } One } A - protected Abstract voidOntriggerenter (Collider other); - the voidOntriggerexit (Collider other) - { - This. Obstacles. Remove (other.gameobject); - } + - Public BOOLisunblocked () + { A for(inti =0; I < This. Obstacles. Count; i++) at { - if( This. obstacles[i]! =NULL&& This. obstacles[i].collider.enabled) - { - return false; - } - } in return true; - } to}
Obstacle detectors for enemy tanks
All types of enemy tanks have the same collision effect, so use the following script uniformly:
1 Public classEnemyobstacledetector:obstacledetector {2 3 protected Override voidOntriggerenter (Collider other)4 {5 varTag =Other.tag;6 if(Tag! =NULL)7 {8 if(tag = = Tags.enemyobstacledetector) {return; }9 if(tag = = Tags.playerobstacledetector) {return; }Ten //for enemy tanks, another enemy tank can penetrate the past, so it should not be added to the obstacles list. One if(tag = = Tags.enemyobstacledetectorcenter) {return; } A } - - This. Obstacles. ADD (other.gameobject); the } -}
For enemy tanks, another enemy tank can penetrate the past, so it should not be added to the obstacles list.
If you meet someone else's cube (obstacle detector), simply ignore it.
Obstacle detectors for players ' tanks
Player tanks have different effects from enemy tanks, so they need to be handled separately.
1 Public classPlayerobstacledetector:obstacledetector2 {3 4 protected Override voidOntriggerenter (Collider other)5 {6 varTag =Other.tag;7 if(Tag! =NULL)8 {9 if(tag = = Tags.enemyobstacledetector) {return; }Ten if(tag = = Tags.playerobstacledetector) {return; } One } A - This. Obstacles. ADD (other.gameobject); - } the -}
For player tanks, other tanks are not able to penetrate.
Similarly, if you encounter someone else's cube (obstacle detector), simply ignore it.
Inheritance and Getcomponent
Obstacledetector is an abstract base class in which enemy tanks and player tanks use their subclasses Enemyobstacledetector and Playerobstacledetector respectively. . At this point,getcomponent<T> () can still be used normally. It returns a reference to a base class object that actually points to the object of a subclass.
This is a generic knowledge.
1 Public classTanktranslate:monobehaviour2 {3 PrivateSystem.collections.generic.dictionary<tanktoward, obstacledetector>obstacledetectordict;4 5 //Use this for initialization6 voidStart ()7 {8 if(Obstacledetectordict = =NULL)9{obstacledetectordict =NewSystem.collections.generic.dictionary<tanktoward, obstacledetector>(); }Ten varNames =New string[] {"forward","Backward"," Left"," Right" }; One varDirection =Newtanktoward[] {tanktoward.z, tanktoward.nz, Tanktoward.nx, tanktoward.x}; A for(inti =0; I < names. Length; i++) - { - varChild = This. Transform. Findchild (Names[i]); the varScript = child. Getcomponent<obstacledetector>(); - Obstacledetectordict.add (Direction[i], script); - } - } +}
Fire, smoke.
The tank is hit with a loss of health value, and the visual effect is shown by the smoke concentration.
The smoke effect is done with the particle system component.
Controlling the concentration of smoke requires a script.
1 Public classTanksmoke:monobehaviour2 {3 Publictankhealth Tankhealthscript;4 Private floatLasthealth;5 6 //Update is called once per frame7 voidUpdate ()8 {9 if(Lasthealth! =tankhealthscript.health)Ten { One varLosthealth = (Tankhealth.maxhealth-tankhealthscript.health); A if(Losthealth <=0) - { - This. particlesystem.enableemission =false; the } - Else - { - This. Particlesystem.play (); + This. particlesystem.enableemission =true; - This. particlesystem.emissionrate = -* Losthealth/Tankhealth.maxhealth; + } ALasthealth =Tankhealthscript.health; at } - } -}
Pictures of smoke footage from the original tank fleet are:
For normal display, you need to set its shader to mobile Particles/alpha blended, and set tiling and offset as shown.
If you do not understand the meaning of tiling and offset, you can refer to here (Unity3d material tiling and offset in the text).
+bit Wei Wei + quietly left a version of the right to say:
If you need project source code, please donate 10 yuan through the QR code below and leave your contact information.
PS: Thanks to the last donation, although there are only 1 people. This article as feedback, I hope you are satisfied.
PS: I changed the blog skin, I feel better.
[Unity3d] DIY tank Fleet Armadatank (2) from the collision