What do you do in the next Simba? The new issue of the game came out again (obviously is a demo ah Hello), this time the game is simpler than ever (you do not deceive me), but more beautiful than ever (excuse me?), yes, that is animation! This game uses animation systems that have not been used before and uses other people's models (no faces).
Garen Model: Http://pan.baidu.com/s/1i5exKNV
Before use, set all models and actions to Legacy animation, Inspector, Rig, Animation type , Legacy , apply button.
Let's take a look at this cool effect: (This ...) Is this a ...? Gallian? )
The rules of the game are simple, the player controls Galen hitting the end of the 7 ball game on the field and giving the final time.
class diagram of the game:
(The deal is simple?) I do not know how to understand it is not urgent, it looks very complicated, in fact, only 3 scripts to write, saying that this picture may be wrong, just learn UML drawing.
Step Description:
First, scene layout
The scene layout always must consider and perfect when the game starts to produce, before playing the code to have the brain to complement the game normal operation situation. I designed the game camera is not moving, the player can be in the fixed area through the WASD movement, click the left mouse button to attack. When all the balls in the area have been hit and gone, the game is over and the player is displayed.
First drag the player Garen into the scene, reset position. Create a new 4 cube and a plane to form a block area by stretching and shifting:
To add a rigid body assembly and a collision box to the player, the collision box uses a capsule body:
Create a new 1 UI text object and position it in the center of the screen to display the player's final time:
All objects in the scene:
Second, player action
OK, you can start writing the code. To write from the most intuitive, then write the player's control first. The player has 3 actions, namely idle, Run, Attack. When Idle is played at start, run needs to detect the keyboard input in the update and use Getaxisraw to get the direction of WASD. Attack is a complex action that, by registering a callback function during an action, can trigger these functions, such as the Attackhit function, as well as the Stopattack function, during attack animation playback. The former judge has no hit object and broadcasts a hit message. The latter causes the player to play standing animations (which stand after the attack animation is over).
Using unityengine;using System.collections;public class Garenmovement:monobehaviour {Animation ani; Animationstate Idle; Animationstate run; Animationstate attack; public float speed = 5f; Vector3 movement; Rigidbody Playerrigidbody; BOOL isattacking = false; float raylength = 1.8f; public delegate void Attackhithandler (Gameobject obj); public static event Attackhithandler Onattackhit; void Start () {playerrigidbody = this. Getcomponent<rigidbody> (); ANI = this. Getcomponent<animation> (); Idle = ani["Idle"]; Run = ani["Run"]; Attack = ani["Attack1"]; Default Playback stand Animation Idle.wrapmode = Wrapmode.loop; Ani. Play (Idle.clip.name); }void Fixedupdate () {if (!isattacking) {float h = input.getaxisraw ("horizontal"); Float v = input.getaxisraw ("Vertical"); Move (h, v); } if (Input.getmousebuttondown (0)) {Attack (); }} void Move (float h, float v) {if (h! = 0 | | V! = 0) {movement. Set (H, 0f, V); Mobile Player Position movement = movement.normalized * speed * time.deltatime; Playerrigidbody.moveposition (transform.position + movement); Rotate player angle quaternion newrotation = quaternion.lookrotation (movement); Playerrigidbody.moverotation (newrotation); Play running animation run.wrapmode = Wrapmode.loop; Ani. Crossfade (Run.clip.name, 0.1f); } else {ani. Crossfade (Idle.clip.name, 0.1f); }} void Attack () {isattacking = true; if (Attack.clip.events.Length = = 0) {//Add the callback function after the end of the attack animation animationevent endevent = new Animati OnEvent (); Endevent.functionname = "Stopattack"; Endevent.time = attack.clip.length-0.2f; Attack.clip.AddEvent (endevent); Add a callback function in an attack animation Animationevent hitevent = new Animationevent (); Hitevent.functionname = "Attackhit"; Hitevent.time = 0.5f; Attack.clip.AddEvent (hitevent); } ani. Play (Attack.clip.name); } void Stopattack () {isattacking = false; } void Attackhit () {//Ray judgment Gameobject obj = Gameobject.find ("C_buffbone_glb_center_loc"); Ray Ray = new Ray (obj.transform.position, movement); Raycasthit hit; if (Physics.raycast (Ray, out hit, raylength)) {Debug.drawline (Ray.origin, hit.point); Onattackhit (Hit.collider.gameObject); } }}
Ray collision detection is very interesting, if the simple mesh collider to detect the impact, at least I did not think of any good method, seemingly grid collision detection is passive, active only ray detection. The trick here is to set the length of the ray to the length of the knife, and then make a point set to Garen's waist, which can be very good to detect whether the Garen knife "cut" in the object.
In addition, the delegate object completes the work of the Attackhithandler and Hitevent classes in the UML diagram, so the actual code is not as complex.
What is delegate? It's like a public number, and anyone can focus on it. Suddenly one day, the public announced Kobe Bryant retired! If the person who is concerned with this public number can immediately know the news, but everyone can make a different response, or sad or happy, because of people, and the public number is not related. Delegate is only responsible for broadcasting news, but not to pursue the results after the press release.
Third, the referee class
Now the player can perform a variety of actions, but I do not know whether my attackhithandler can work properly, so quickly wrote the referee Judge class to verify:
Using unityengine;using system.collections;using Com.mygame;public class Judge:monobehaviour {public int count = 7; void Start () { garenmovement.onattackhit + = hitevent;} void Hitevent (Gameobject obj) { if (obj.tag.Contains ("Ball")) { obj. SetActive (false); if (--count = = 0) { myui.getinstance (). Display (Time.time.ToString ());}}}
The UI is later changed and can be tested with print or debug when not written. remember to add tags.
Four, factory class
Now it's time to think about spheres, creating a factory to manage these spheres is a good way to create a new Basecode script to write a singleton class, and define a namespace by the way:
Using unityengine;using unityengine.ui; Using system.collections;using system.collections.generic;using com.mygame;namespace Com.mygame{public class BallFactory:System.Object {static Ballfactory instance; Static list<gameobject> balllist; public static Ballfactory getinstance () {if (instance = = null) {instance = n EW ballfactory (); Balllist = new list<gameobject> (); } return instance; Gameobject Getball () {for (int i = 0; i < Balllist.count; ++i) { if (!balllist[i].activeinhierarchy) {return balllist[i]; }} gameobject NEWOBJ = Gameobject.createprimitive (Primitivetype.sphere); Newobj.getcomponent<renderer> (). Material.color = Color.green; Newobj.tag = "Ball"; Balllist.add (NEWOBJ); return NEWOBJ; } }}
Take into account that the recovery can be completely through ball. SetActive (false) complete, let the judge to complete.
V.UI
The UI is so important to forget, add in the namespace:
public class MyUI:System.Object { static Myui instance; Public Text MainText; public static Myui getinstance () { if (instance = = null) { instance = new Myui (); } return instance; } public void Display (string info) { maintext.text = info; } }
Vi. Scenario Initialization
Everything is ready, only owed the initial. Basecode just can be used to initialize the scene. Start generates 7 balls randomly within the region and assigns the Myui Maintext object:
public class Basecode:monobehaviour {public int balls = 7; public text text; void Start () { myui.getinstance (). MainText = text; for (int i = 0; i < balls; ++i) { Gameobject ball = ballfactory.getinstance (). Getball (); Ball.transform.position = new Vector3 (Random.range ( -10f, 10f), 1f, Random.range ( -10f, 10f));}}}
The code is finished (simple, just 200 lines), you have to mount them on the game object, I put the garenmovement script mounted on the player Garen, ballfactory and Basecode mounted on the Maincamera, run a bit, ok!
All code
GarenMovement.cs
Using unityengine;using System.collections;public class Garenmovement:monobehaviour {Animation ani; Animationstate Idle; Animationstate run; Animationstate attack; public float speed = 5f; Vector3 movement; Rigidbody Playerrigidbody; BOOL isattacking = false; float raylength = 1.8f; public delegate void Attackhithandler (Gameobject obj); public static event Attackhithandler Onattackhit; void Start () {playerrigidbody = this. Getcomponent<rigidbody> (); ANI = this. Getcomponent<animation> (); Idle = ani["Idle"]; Run = ani["Run"]; Attack = ani["Attack1"]; Default Playback stand Animation Idle.wrapmode = Wrapmode.loop; Ani. Play (Idle.clip.name); }void Fixedupdate () {if (!isattacking) {float h = input.getaxisraw ("horizontal"); Float v = input.getaxisraw ("Vertical"); Move (h, v); } if (Input.getmousebuttondown (0)) {Attack (); }} void Move (float h, float v) {if (h! = 0 | | V! = 0) {movement. Set (H, 0f, V); Mobile Player Position movement = movement.normalized * speed * time.deltatime; Playerrigidbody.moveposition (transform.position + movement); Rotate player angle quaternion newrotation = quaternion.lookrotation (movement); Playerrigidbody.moverotation (newrotation); Play running animation run.wrapmode = Wrapmode.loop; Ani. Crossfade (Run.clip.name, 0.1f); } else {ani. Crossfade (Idle.clip.name, 0.1f); }} void Attack () {isattacking = true; if (Attack.clip.events.Length = = 0) {//Add the callback function after the end of the attack animation animationevent endevent = new Animati OnEvent (); Endevent.functionname = "Stopattack"; Endevent.time = attack.clip.length-0.2f; Attack.clip.AddEvent (endevent); Add a callback function in an attack animation Animationevent hitevent = new Animationevent (); Hitevent.functionname = "Attackhit"; Hitevent.time = 0.5f; Attack.clip.AddEvent (hitevent); } ani. Play (Attack.clip.name); } void Stopattack () {isattacking = false; } void Attackhit () {//Ray judgment Gameobject obj = Gameobject.find ("C_buffbone_glb_center_loc"); Ray Ray = new Ray (obj.transform.position, movement); Raycasthit hit; if (Physics.raycast (Ray, out hit, raylength)) {Debug.drawline (Ray.origin, hit.point); Onattackhit (Hit.collider.gameObject); } }}
Judge.cs
Using unityengine;using system.collections;using Com.mygame;public class Judge:monobehaviour {public int count = 7; void Start () { garenmovement.onattackhit + = hitevent;} void Hitevent (Gameobject obj) { if (obj.tag.Contains ("Ball")) { obj. SetActive (false); if (--count = = 0) { myui.getinstance (). Display (Time.time.ToString ());}}}
BaseCode.cs
Using unityengine;using unityengine.ui; Using system.collections;using system.collections.generic;using com.mygame;namespace Com.mygame{public class Myui:sy Stem. Object {static Myui instance; Public Text MainText; public static Myui getinstance () {if (instance = = null) {instance = new Myui (); } return instance; The public void Display (string info) {Maintext.text = info; }} public class BallFactory:System.Object {static ballfactory instance; Static list<gameobject> balllist; public static Ballfactory getinstance () {if (instance = = null) {instance = n EW ballfactory (); Balllist = new list<gameobject> (); } return instance; } public Gameobject Getball () {for (int i = 0; i < Balllist.count ++i) {if (!balllist[i].activeinhierarchy) {return balllist[i ]; }} gameobject NEWOBJ = Gameobject.createprimitive (Primitivetype.sphere); Newobj.getcomponent<renderer> (). Material.color = Color.green; Newobj.tag = "Ball"; Balllist.add (NEWOBJ); return NEWOBJ; }}}public class Basecode:monobehaviour {public int balls = 7; public text text; void Start () {myui.getinstance (). MainText = text; for (int i = 0; i < balls; ++i) {Gameobject ball = ballfactory.getinstance (). Getball (); Ball.transform.position = new Vector3 (Random.range ( -10f, 10f), 1f, Random.range ( -10f, 10f)); } }}
Unity3d Study Notes (7)--Batting games