I’m making a sprite-based game with minimal 3D effects (using 3D planes as the “sprites”) and I’m trying to get my main character walking round. This technically WORKS, but it’s very wonky and can’t decide which frame it wants to be on. So is there any way this could be fixed?
var StaticFrame : Texture;
var WalkVert1 : Texture;
var WalkVert2 : Texture;
var WalkLeft1 : Texture;
var WalkLeft2 : Texture;
var WalkLeft3 : Texture;
var WalkRight1 : Texture;
var WalkRight2 : Texture;
var WalkRight3 : Texture;
var timing = .55;
function Update () {
if(Input.GetKey("w")){
WalkyAnim("vert");
}
else if(Input.GetKey("s")){
WalkyAnim("vert");
}
else if(Input.GetKey("a")){
WalkyAnim("left");
}
else if(Input.GetKey("d")){
WalkyAnim("right");
}
else{
ResetAnims();
}
}
function WalkyAnim(animdir : String){
if(animdir=="vert"){
renderer.material.mainTexture = WalkVert1;
yield WaitForSeconds(timing);
renderer.material.mainTexture = WalkVert2;
}
else if(animdir=="left"){
renderer.material.mainTexture = WalkLeft1;
yield WaitForSeconds(timing);
renderer.material.mainTexture = WalkLeft2;
yield WaitForSeconds(timing);
renderer.material.mainTexture = WalkLeft3;
}
else if(animdir=="right"){
renderer.material.mainTexture = WalkRight1;
yield WaitForSeconds(timing);
renderer.material.mainTexture = WalkRight2;
yield WaitForSeconds(timing);
renderer.material.mainTexture = WalkRight3;
}
}
function ResetAnims(){
yield WaitForSeconds(2);
renderer.material.mainTexture = StaticFrame;
}
I realise that I need to use GetKeyDown instead of GetKey, but a simple replace won’t work.
you could try adding 3 timers one for the start of frame 2 and tell it to stop frame 1, then a second timer to do the same with frame 3 and 2, and final one to end frame 3 and start start the script again
var StaticFrame : Texture;
var WalkVert1 : Texture;
var WalkVert2 : Texture;
var WalkLeft1 : Texture;
var WalkLeft2 : Texture;
var WalkLeft3 : Texture;
var WalkRight1 : Texture;
var WalkRight2 : Texture;
var WalkRight3 : Texture;
var timing = .55;
var timing2 = 1.1;
var timing3 = 1.65;
function Update () {
if(Input.GetKey("w")){
WalkyAnim("vert");
}
else if(Input.GetKeyDown("s")){
WalkyAnim("vert");
}
else if(Input.GetKeyDown("a")){
WalkyAnim("left");
}
else if(Input.GetKeyDown("d")){
WalkyAnim("right");
}
else{
ResetAnims();
}
}
function WalkyAnim(animdir : String){
if(animdir=="vert"){
renderer.material.mainTexture = WalkVert1;
yield WaitForSeconds(timing);
renderer.material.mainTexture = WalkVert2;
yield WaitForSeconds(timing2);
}
else if(animdir=="left"){
renderer.material.mainTexture = WalkLeft1;
yield WaitForSeconds(timing);
renderer.material.mainTexture = WalkLeft2;
yield WaitForSeconds(timing2);
renderer.material.mainTexture = WalkLeft3;
yield WaitForSeconds(timing3);
}
else if(animdir=="right"){
renderer.material.mainTexture = WalkRight1;
yield WaitForSeconds(timing);
renderer.material.mainTexture = WalkRight2;
yield WaitForSeconds(timing2);
renderer.material.mainTexture = WalkRight3;
yield WaitForSeconds(timing3);
}
}
function ResetAnims(){
yield WaitForSeconds(2);
renderer.material.mainTexture = StaticFrame;
}
Might work i dunno i’ve never done this before but assuming you used the right formula then this addaptation should wor
It would seem to be that every update, you call the function Again and the process starts over while another process continues. So in some way, you will have create a way similar to a singleton that keeps your animation from overriding its self.
Another problem that is not directly causing you problems, but is hurting your structure is how you implemented your animation system in the first place. It hurts to say it, I know you are going for simplicity, but it would work better if you treated each animation as its own object or at least put it in an array which would also be an object anyway. That’s basically what sprite manager does, except on a side note, I believe it puts all the images in one big texture and then creates a Rect[ ]. That lets you do easier cycling through the images and do things like play forward, loop and play reverse.
Here are some wiki posts that might guide you. I would think creating a Texture2D[ ] might be your best option, plus you have to create a way to stop overriding your previous animation. A bool like isPlaying implemented well could do exactly that.
Yes, that is what it is designed for. Unity doesn’t have a Sprite Engine (sorry to be Mr.Obvious ) so all the sprite systems are based using planes in 3d space.
Being stupid, I really can’t figure out SpriteManager and I’d really rather not make a sprite sheet. I’m really happy with my “simple” method, I won’t be using a lot of animations. Do you have any suggestions for that?
EDIT: This actually works, except I can’t get it to reset to the static frame once the animation is done. Putting an “else” in the update, and saying simply “else, ResetAnims” doesn’t work quite right.
var StaticFrame : Texture;
var WalkVert1 : Texture;
var WalkVert2 : Texture;
var WalkLeft1 : Texture;
var WalkLeft2 : Texture;
var WalkLeft3 : Texture;
var WalkRight1 : Texture;
var WalkRight2 : Texture;
var WalkRight3 : Texture;
var timing = .55;
function Update () {
if(Input.anyKey==true){
if(Input.GetKeyDown("w")){
WalkyAnim("vert");
}
else if(Input.GetKeyDown("s")){
WalkyAnim("vert");
}
else if(Input.GetKeyDown("a")){
WalkyAnim("left");
}
else if(Input.GetKeyDown("d")){
WalkyAnim("right");
}
}
}
function WalkyAnim(animdir : String){
if(animdir=="vert"){
renderer.material.mainTexture = WalkVert1;
yield WaitForSeconds(timing);
renderer.material.mainTexture = WalkVert2;
}
else if(animdir=="left"){
renderer.material.mainTexture = WalkLeft1;
yield WaitForSeconds(timing);
renderer.material.mainTexture = WalkLeft2;
yield WaitForSeconds(timing);
renderer.material.mainTexture = WalkLeft3;
}
else if(animdir=="right"){
renderer.material.mainTexture = WalkRight1;
yield WaitForSeconds(timing);
renderer.material.mainTexture = WalkRight2;
yield WaitForSeconds(timing);
renderer.material.mainTexture = WalkRight3;
}
}
function ResetAnims(){
yield WaitForSeconds(2);
renderer.material.mainTexture = StaticFrame;
}
try setting the animation from the project window to wrap mode → Once, in the inspector window and the engine should reset the anim once it has finished playing.