纳金网

标题: 角色的动作3.3---射击游戏系列教程之三 [打印本页]

作者: 会飞的鱼    时间: 2011-11-21 15:20
标题: 角色的动作3.3---射击游戏系列教程之三


           Go ahead and***n your game, is your character animating? If not have a look at my version of this
           

           project and see if there's something off in your code or unity editor. Maybe I've made a mistake here
           

           (goodness I hope not). If so let me know. But let's go through each section of code and I will explain
           

           what it is doing.
           

           void HandleAnimation () // handles all animation
           

           {
           

           FindAnimation();
           

           ProcessAnimation();
           

           }
           

           HandleAnimation is simply calling the FindAnimation then the ProcessAnimation function.
           

           void FindAnimation ()
           

           {
           

           if (inputMovement.magnitude > 0)
           

           {
           

           currentAnimation = animationWalk;
           

           } else {
           

           currentAnimation = animationStand;
           

           }
           

           }
           

           We are using an IF statement to see whether the inputMovement Vector's magnitude is greater than 0.
           

           Magnitude is the size of the Vector, if it is 0 the player is not inputting any movement, if the player is
         

           pressing a key because the Vector is being set to that, the magnitude of the Vector will also increase.
           

           And as such depending on what the player is doing we want to play the correct animation.
           

           I have added as many comments which have come to mind to the ProcessAnimation function, I shall
           

           try to elaborate a little more below:
           

           void ProcessAnimation ()
           

           {
           

           animationTime -= Time.deltaTime; // animationTime -= Time.deltaTime;
           

           subtract the number of seconds passed since the last frame, if the game is***nning at 30 frames per
           

           second the variable will subtract by 0.033 of a second (1/30)
           

           if (animationTime <= 0)
           

           {
           

           frameNumber += 1;
           

           The first calculation on the variable 'animationTime' is subtracting the time since the last frame (or last
           

           time this function was called from this variable. If animationTime is less than 0, the frame number
           

           increments by a value of 1, meaning the next frame will be played.
           

           if (currentAnimation == animationStand)
           

           {
           

           frameNumber =
           

           Mathf.Clamp(frameNumber,standAnimationMin,standAnimationMax+1);
           

           if (frameNumber > standAnimationMax)
           

           {
           

           frameNumber = standAnimationMin;
           

           }
           

           }
           

           If we are playing the stand animation (ie the player is not giving any input on the keyboard) we are
           

           going to clamp the frameNumber value between 2 other values, the Clamp ins***ction does just that.
           

           For example, if frameNumber was equal to 3, and I went to clamp it between 5 and 10, the number
           

           would jump up to the nearest number within that range, in this example frameNumber would become 5.
           

           I do this because I don't want frameNumber to be outside of the frame number that it should be.
           

           Otherwise you might want to play a stand animation and it is half way through the walk animation. If
           

           it happens to be half way through the walk animation I want to clamp it back into the stand animation
           

           range. Next I check to see if the frameNumber has exceeded the maximum number of frames for the
           

           stand animation, if it has I set it back to the beginning and it will cycle once again.
           

           This effectively sets the variable frameNumber, to the frame number that should be displayed on the
           

           character.
           

           spriteSheetCount.y = 0;
           

           for (i=(int)frameNumber; i > 5; i-=5) // find the number of frames down the animation is
           

           and set the y coordinate accordingly
           

           {
           

           spriteSheetCount.y += 1;
         

           }s
           

           priteSheetCount.x = i - 1; // find the X coordinate of the frame to play
           

           spriteSheetOffset = new Vector2(1 - (spriteSheetCount.x/spriteSheetTotalRow),1 -
           

           (spriteSheetCount.y/spriteSheetTotalHigh)); // find the X and Y coordinate of the frame to display
           

           renderer.material.SetTextureOffset ("
           


            _
           
           MainTex", spriteSheetOffset); // offset the texture to
           

           display the correct frame
           

           This code I wont explain the detailed mathematics of. It simply finds out what frame number it is at,
           

           and offsets the texture accordingly. If the frame is number 5 then it wants to use the frame in the top
           

           right corner of our character image. If the frame is number 6, it wants to use the first frame on the
           

           second row etc. This code makes sure it aligns the texture on the character to make sure it accurately
           

           plays the correct frame.
           

           *** but what about the fact that our character doesn't rotate from the center of his body?
           

           Let's try a quick fix add a new variable:
           

           private Vector2 spriteSheetCount; // the X, Y position of the frame
           

           private Vector2 spriteSheetOffset; // the offset value of the X, Y coordinate for the texture
           

           public Vector2 spriteSheetOriginOffset;
           

           This is a variable you can set from your editor in Unity, that way if the offset is different for different
           

           sprite sheets you can adjust it accordingly. Great thing about Unity is that I can change these values
           

           while the game is***nning and see the changes right in front of me! Using trial and error I set an X
           

           value to -0.003 and a Y value to 0.045.
           

           Now let's add it to our code:
           

           spriteSheetOffset = new Vector2(1 - (spriteSheetCount.x/spriteSheetTotalRow),1 -
           

           (spriteSheetCount.y/spriteSheetTotalHigh)); // find the X and Y coordinate of the
           

           frame to display
           

           spriteSheetOffset += spriteSheetOriginOffset;
           

           renderer.material.SetTextureOffset ("
           
            _
           
           MainTex", spriteSheetOffset); // offset the
           

           texture to display the correct frame
           

           Here I am just adding the offset we specified to how much we are offsetting the texture.
           

           There is a small problem with this fix and that is a tiny shadow artifact which appears on the edge of
           

           the sprite. As another frame leaks onto the image. The solution I offered above is a quick one, if you
           

           wanted to try a more complicated option you can remove the mesh renderer and mesh filter component
           

           from your game object, and create a child game object to your player which only contains the mesh
           

           filter and mesh renderer, add your sprite to it. Then create a public GameObject variable in your player
           

           script, drag the child object onto the variable in the inspector which is on the parent object. And in
           

           your script change the following.
           

           yourGameObjectVariable.renderer.material.SetTextureOffset ("
           
            _
           
           MainTex", spriteSheetOffset);
           

           This is how I am doing it from now on, did the last method just to show you a potential work around.
           

           Feel free to see how I've set it up in the example project.
           

           Don't Forget to save your scene Goto > File > Save Scene.
           

           You're ready for Enemy AI!
         

           保存场景,下一章节将来实现敌人的AI功能。附件为本章节所用到的完整代码文件!出处:
           
            www.unity3d8.com
           


作者: 菜刀吻电线    时间: 2012-3-18 23:30
其实楼主所说的这些,俺支很少用!

作者: 晃晃    时间: 2012-5-25 23:24
无聊时可以刷屏幕 灌水 也可以试试 帖子的标题究竟可以写多长

作者: C.R.CAN    时间: 2012-6-12 23:23
加精、加亮滴铁子,尤其要多丁页丁页

作者: tc    时间: 2012-8-11 00:01
呵呵,真得不错哦!!

作者: tc    时间: 2012-10-24 23:20
我就看看,我不说话

作者: C.R.CAN    时间: 2013-2-15 23:31
不错哦,顶一下......

作者: tc    时间: 2013-2-28 23:31
我看看就走,你们聊!





欢迎光临 纳金网 (http://go.narkii.com/club/) Powered by Discuz! X2.5