- 最后登录
- 2014-10-23
- 注册时间
- 2011-7-19
- 阅读权限
- 90
- 积分
- 81303
 
- 纳金币
- -1
- 精华
- 11
|
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
|
|