Study the Unity3d AngryBots project to understand the basic game operating mechanism:
1. character action control logic
* ** Player Object ***
[Shape]
The Player object contains a Skinned Mesh Renderer component, which uses the Mesh name main_player_lorez.
Similarly, there is a GameObject named main_weapon001 that expresses the weapon.
[Operation]: (InputManager)
** Move **
Definition:
Mobile adds two operation methods in InputManager:
Horizontal movement, named Horizontal
Vertical Movement, called Vertical
Some attributes are set, such as the corresponding buttons, acceleration, and type.
In the script (PlayerMoveController. js), you can use Input. GetAxis ("Horizontal") and Input. GetAxis ("Vertical") to obtain the direction in which the player's key state is converted to motion.
And stored in the MovementMotor. js variable defined by the script.
Implementation:
Player adds the RigidBody component, which provides the ability to change the Transform of the GameObject according to the physical law.
In the FreeMovementMotor. js script, some parameters are defined to calculate the Force acting on the RigidBody object together with movementDirection ). The role begins to move in the specified direction.
** FacingDirection )**
Directly use Input. mousePosition as the screen coordinate, define a plane with the role's position, obtain the ray focus, and take the direction from the role's position to the point as the orientation.
And stored in the facingDirection variable defined by the MovementMotor. js script.
[Action playback]: Player Animation (Script) (PlayerAnimation. js)
Var moveAnimations: MoveAnimation []; because it is a public variable, you can directly modify it in inspector,
Six actions run_forward/run_backward/run_right/run_left and idle/turn are defined in the example.
In this example, the role Action defines six clip, which correspond to the preceding six action names one by one.
The playback of an action does not occur when the player is switched or ASWD is pressed.
This script compares the change of the Player's Transform within two frames. It calculates the specific action to play based on the orientation and movement directions.
At the same time, there is a mixed action logic, so that the switching of actions is smooth and smooth.
The upper half rotates to a certain angle, and the lower half is adjusted. This is also a logical function.
2. The entire processing process from shooting to hit, shooting effect production principle
[Create a bullet]
Cache object
ObjectCache class
Var prefab: GameObject;
Var cacheSize: int = 10;
Spawner. js
Var caches: ObjectCache [];
Function Awake (){
Caches [I]. Initialize ();
}
Static function Spawn (...);
Static function Destroy (...);
There is an object cache pool, that is, an instance of the objectCache object,
This object initializes a fixed number of object instances and provides object instances in sequence.
The Spawner object organizes multiple ObjectCache objects according to the Prefab type,
The Spawn and Destroy functions provide unified interfaces to create and Destroy various object instances, such as bullets and missiles.
[Timing of bullet launching]
WeaponSlot
Trig‑mouseorjoystick. Js
Public var mouseDownSignals: SignalSender;
Public var mouseUpSignals: SignalSender;
SignalSender. js
Public function SendSignals (sender: MonoBehaviour)
Public var receivers: ReceiverItem [];
AutoFire. js
Function Update ()
If (firing ){
If (Time. time> lastFireTime + 1/frequency ){
Var go: GameObject = Spawner. Spawn (bulletPrefab, spawnPoint. position, spawnPoint. rotation * coneRandomRotation) as GameObject;
The WeaponSlot (GameObject) object has a script component named trig‑mouseorjoystick.
The update method of this script uses Input. GetMouseButtonDown (0) to monitor the press status of the left mouse button, and uses the SignalSender object to send the event Fire.
SignalSender is essentially a publishing and subscription mode. EventSource declares the SignalSender variable,
To declare the event name that will be initiated, and call SignalSender. SendSignals (this) to fire the event whenever necessary.
The receiver of the event is given by the receivers variable of SignalSender.
Because it is a global variable, it can be set in inspector.
The customer's processing logic is associated with the event source in this way.
The event name is also set through inspector.
The SendSignals method accepts parameters of the MonoBehaviour type. Therefore, you can use this event mechanism to call different functions in different scripts.
Due to the implementation principle of SendMessage of GameObject, you only need to ensure that the receiver of the event contains a function with the same name as the event, which is automatically called.
(Doubt: This method does not contain parameters. What should I do if I need to transmit additional parameters to the Event? Can think of data exchange in a public place)
Through SignalSender, the logic state of the weapon-"fire"-has been recognized by the logic. The example saves the result in the firing variable of the AutoFire script.
After opening fire, the Instance Object of the bullet is activated in AutoFire.
[Fire effects]
WeaponSlot
AutoFire. js
MuzzleFlashFront. active = true;
Audio. Play ();
Through SignalSender, the logic status of the weapon-"fire"-has been recognized by the logic,
In this example, the result is saved in the firing variable of the AutoFire script. At the same time, some special fire effects were also played:
* The Sound Effects of weapon fire, which only calls the AudioSource component.
* Specifies a GameObject in inspector as a muzzleFlashFront object.
It contains some Mesh and a Light, as well as a script that rotates and scales the Mesh to achieve a cool jet.
* Shooting actions of a character-implemented by another set of listeners, which are not triggered in the AutoFire script.
[Hit events]
PerFrameRaycast. js
Private var hitInfo: RaycastHit;
AutoFire. js (hit determination)
Var hitInfo: RaycastHit = raycast. GetHitInfo ();
AutoFire. js (repel enemies)
Var force: Vector3 = transform. forward * (forcePerSecond/frequency );
HitInfo. rigidbody. AddForceAtPosition (force, hitInfo. point, ForceMode. Impulse );
AutoFire. js (sound effects hit by playback)
Var sound: AudioClip = MaterialImpactManager. GetBulletHitSound (hitInfo. collider. sharedMaterial );
AudioSource. PlayClipAtPoint (sound, hitInfo. point, hitSoundVolume );
The hit in the game is irrelevant to the bullet flight. It is determined by the ray query results provided by the PerFrameRaycast. js script.
PerFrameRaycast performs a ray query every frame and stores the result in hitInfo.
During the update process, AutoFire checks whether the object is hit.
If an object is hit, calculate the damage and call the relevant methods of the Health script component. (Health-related things will be described in detail later)
[Bullet flight]
A bullet is a GameObject named InstanceBullet,
It is described by the Prefab object named InstanceBullet,
It mainly contains a long mesh that expresses the bullet trajectory, and a script SimpleBullet. js used to control its flight.
SimpleBullet. js
Function Update (){
Tr. position + = tr. forward * speed * Time. deltaTime;
Function Update (){
If (Time. time> spawnTime + lifeTime | dist <0 ){
Spawner. Destroy (gameObject );
SimpleBullet. js contains some parameters to ensure that the bullet has the following actions:
Flight along the created direction
There is a time limit, the time will be sleep (Spawner. Destroy)
There is a distance limit. If the distance is exceeded, it will sleep (Spawner. Destroy)
AutoFire. js
Bullet. dist = hitInfo. distance;
Except for the above two methods, bullets can pass through the stones in the scene, but cannot cross the box or cross the scene boundary exposed after the stone is removed.
This is because when AutoFire makes a hit decision, the maximum bullet distance parameter is adjusted based on the results of the ray query.
3. How monsters activate, attack, and action control work. How the Special Attack Effects of KamikazeBuzzer, the first monster you encounter, are realized.
[1st KamikazeBuzzer]
SimpleBuzzers7
EnemyArea. js
Box Collider
KamikazeBuzzer
KamikazeMovementMotor. js
BuzzerKamikazeControllerAndAi. js
DestroyObject. js
Health. js
AudioSource
[Shape]
Buzzer_bot
[Action]
This monster's mesh does not work.
[Activate]
EnemyArea. js
Function OnTriggerEnter (other: Collider ){
If (other. tag = "Player ")
ActivateAffected (true );
When the role enters the Box Collider range, OnTriggerEnter is triggered,
In this case, the sub-object KamikazeBuzzer of SimpleBuzzers7 is set to active. The script component mounted to the KamikazeBuzzer object can be executed.
[Move]
KamikazeMovementMotor. js
This script controls the attributes of the Rigid Body of KamikazeBuzzer, calculates the output based on parameters and certain calculation rules, acts on the rigid body, and enables KamikazeBuzzer to move, similar to the movement principle of Player.
BuzzerKamikazeControllerAndAi. js
The script calculates the parameters required by KamikazeMovementMotor Based on the positional relationship between the monster and the Player according to certain calculation rules, so as to control its movement.
Direction = (player. position-character. position );
Because the direction is always toward the player, there seems to be a "chase" effect.
RechargeTimer <0.0f & threatRange & Vector3.Dot (character. forward, direction)> 0.8f
This judgment achieves the "overhead" effect.
[Special Attack Effects]
When the "catch" condition is reached in the mobile process, the DoElectricArc function is called to express the attack method.
ZapNoise = Vector3 (Random. Range (-1.0f, 1.0f), 0.0f, Random. Range (-1.0f, 1.0f) * 0.5f;
ZapNoise = transform. rotation * zapNoise;
Here there is a small random, in order to make the position of each power to the Player different.
Public var electricArc: LineRenderer;
ElectricArc. SetPosition (0, electricArc. transform. position );
ElectricArc. SetPosition (1, player. position + zapNoise );
It mainly relies on LineRenderer to describe the lightning arc.
LineRenderer is used to construct several consecutive line segments. You can set the start width and end width.
[Attacked]
DamagePos (GameObject)
Transform (Component)
KamikazeBuzzer (GameObject)
Health. js
Health. js
Private var damageEffect: Participant emitter;
Function OnDamage (amount: float, fromDirection: Vector3 ){
DamageEffect. Emit ();
The DamagePos object aggregates a Transform component that provides coordinate information for the hit effect.
KamikazeBuzzer aggregates a Health. js, where damageEffect is specified as javasicsparkshita (prefab ).
In the previous bullet hit process, the hit target calls the OnDamage function of its Health component.
The OnDamage of KamikazeBuzzer's Health is to create a ElectricSparksHitA (Clone) object to achieve the special effect of playing.
[Death and explosion]
Health. js
Public var dieSignals: SignalSender;
Function OnDamage (amount: float, fromDirection: Vector3 ){
If (health <= 0)
{
DieSignals. SendSignals (this );
SpawnObject. js
Function OnSignal (){
Spawned = Spawner. Spawn (objectToSpawn, transform. position, transform. rotation );
DestroyObject. js
Function OnSignal (){
Spawner. Destroy (objectToDestroy );
When the health value is reduced to 0 or less, the object is declared dead.
The DamagePos object aggregates a SpawnObject. js script. Create an ExplosionSequenceBuzzer (prefab) in its OnSignal function );
ExplosionSequenceBuzzer is used to express the explosion effect. Some particle changes are controlled in its javastsequencer. js script.
The KamikazeBuzzer object aggregates a DestroyObject. js script. The KamikazeBuzzer object instance is destroyed in its OnSignal function.
4. health processing procedures related to characters and monsters
The volume of Player and monster is achieved by aggregating a Health. js script component.
Damage calculation is written independently in the respective components. Player is AutoFire, and KamikazeBuzzer is in its AI script.
The Health component mainly defines
Blood Volume
Special effects
Injury traces
Attacked event
Death event
Collaboration methods are already described when analyzing the behavior patterns of Player and KamikazeBuzzer.
5. Camera follow and Control
PlayerMoveController. js
The camera position is calculated based on the role position. Fine-tune the camera position based on the mouse position.
6. Implementation Principles of effects related to raindrops, including raindrops falling, ripple falling onto the ground, implementation and reflection of surface water, etc.
Raindrops]
[Related GameObject]
Rain
RainBox expresses raindrops
RainEffect: Root object that organizes various things
Root object of RainDrops drop
RainslpashesBig: Root object that expresses the ripple of raindrops
RainslpashesSmall: the Root object that expresses the ripple of raindrops
Splashbox expresses ripple
[Mesh & Material]
RainDrops_LQ0/1/2
RainsplashesBig_LQ0/1/2
RainsplashesSmall_LQ0/1/2
[Shader]
Rain
RainSplash
[Organizational Relationship]
Environment (dynamic)
RainEffects (location 000)
RainDrops (RainManager. js)
RainBox * N
RainBox. js
Rain (Shader)
RainDrops_LQ0 (Mesh)
RainslpashesBig (RainsplashManager. js)
Splashbox
RainsplashBox. js
RainSplash (Shader)
RainsplashesBig_LQ0 (Mesh)
RainslpashesSmall
Splashbox
RainsplashBox. js
RainSplash (Shader)
RainsplashesSmall_LQ0 (Mesh)
[Rain]
RainManager. js
Function CreateMesh (): Mesh {
Public function GetPreGennedMesh (): Mesh {
At runtime, RainManager creates the Mesh and Material of the rain curtain. The idea is to randomly generate small pieces with only four vertices in a fixed rectangular box.
The generated object is related to the name, that is, GameObject. name + _ LQ0/1/2. There are three types of Mesh, except that the positions of the generated slices and uv coordinates are inconsistent.
RainBox. js
Function Update (){
Function OnDrawGizmos (){
The logic in Update allows the rain curtain Mesh to move from top to bottom in the Y direction, so as to achieve the effect of raindrops falling.
The OnDrawGizmos function is used to draw the shape of the rain curtain during editing.
[Creation of Ripple]
RainsplashManager. js
RainsplashBox. js
Ripple is created in the same way as the rain curtain. It is only the coordinates when a small part is generated, and the normal direction is slightly different.
The size and size of the created slices are different.
[Ripple diffusion]
In RainSplash (Shader), the uv coordinates and colors on the uploaded fixed point are modified to make ripple changes from small to small and gradually fade out.
(Doubt) Where is the material specified? Manually specified by inspector?
(Doubt) which calls are prohibited and allowed in RainBox. js enable?
Surface water surface and reflection]
[Related GameObject]
PolySurface5097 Earth Surface
RealtimeReflectionInWateRFlow. shader processes shader for surface simulation and reflection
Main CameraReflectionMain Camera reflection Camera
RealtimeReflectionReplacEment. shader alternative shader Solution
Main Camera
ReflectionFx. cs script for generating reflection textures
Public System. String reflectionSampler = "_ ReflectionTex"; Reflection texture
ReflectionMask
[Key code]
ReflectionFx. cs
Public Transform [] reflectiveObjects;
Private Camera reflectionCamera;
Public LayerMask reflectionMask;
Calculates the position and orientation of the reflection camera, and merges the transformation into a reflection matrix.
Rendering to a reflection texture
RealtimeReflectionInWateRFlow. shader
_ ReflectionTex ("_ ReflectionTex", 2D) = "black "{}
V2f_full vert (appdata_full v)
O. fakeRefl = EthansFakeReflection (v. vertex );
Fixed4 frag (v2f_full I): COLOR0
Fixed4 rtRefl = tex2D (_ ReflectionTex, (I. screen. xy/I. screen. w) + nrml. xy );
RtRefl + = tex2D (_ FakeReflect, I. fakeRefl + nrml. xy * 2.0 );
RealtimeReflectionReplacEment. shader
[LateUpdate]
Process reflection in LateUpdate
Because reflection needs to wait until the motion of all objects ends.
[ReflectiveObjects]
ReflectiveObjects is an object that can generate reflection and is manually added. In this example, there are three objects:
PolySurface5097
PolySurface425
PolySurface5095
[Why is helperCameras Clear?]
HelperCameras is designed to support the reflection of any number of cameras in the game, that is, the versatility of ReflectionFx. cs.
To ensure that only one reflection texture is rendered within one frame, clear the image.
[Filter reflected objects]
ReflectionMask
Objects that can be reflected must be one of the following layers:
Reflection
Player
Enemies
You can set the Layer attribute of GameObject through Inspector.
7. other theme that you think is important
Coroutine. Coroutine is a mechanism that transfers control of code execution, rather than multithreading. Through this mechanism, the code execution process can be made less ordered to achieve the goal of collaboration between various modules.
The AudioSource audio source object needs AudioClip to load the Audio Resource, and AudioListener (ears) is used together to calculate the audio volume.
Animation object, which controls bone Animation and supports mixing and IK.
The WWW-encapsulated URL operation class can support http, https, file, and ftp protocols. Ftp only supports anonymous logon.
NGUI: a lightweight UI Library
Link: http://blog.sina.com.cn/s/blog_4ef78af501013jvq.html