I'm trying to make a game where you're a boy and you can transform into a deer.
I don't know how to make the player transform into a deer when pressing a button. Can someone please tell me how to make the player transform into a deer when pressing a button and how to make the deer transform back into the player when pressing the button again?
There are 2 ways depending on what you want exactly.
1.Transformation without an animation, you can do this by having 2 separate models
public GameObject boy;
public GameObject deer;
//Give both objects the same tag and don't add anything else under the
tag in order for this to work
private Transform currentPosition;
private void Start()
{
deer.SetActive(false);
}
public void TransformButton()
{
currentPosition = GameObject.FindObjectWithTag(LayerMask.NameToLayer("TransformationTag"));
//Unity doesn't pick up disabled GameObjects so it will pick up only the
//active state (the active object)
boy.SetActive(!activeInHierarchy);
deer.SetActive(!activeInHierarchy);
GameObject.FindObjectWithTag(LayerMask.NameToLayer("TransformationTag")).getComponent<Transform>() = currentPosition;
}
I recommend this way if your deer and boy have different scripts
you could also play an animation on click (apply this animation to the active character) and when it is done (below is how to check if it is done) you can trigger the code above
https://answers.unity.com/questions/362629/how-can-i-check-if-an-animation-is-being-played-or.html
I am pretty sure there are other better ways but this is the way I do it
The other way which is probably easier if you are good at animating is to just trigger an animation using the animation bools when the button is clicked but I haven't tried this way because I'm not that good at animation. Instead I use the first way (usually for switching skins in a shop for example) but I never did animations that completely change the size ratio so much so I don't know how well would it work (I usually do 1:1 transformations like humanoid to humanoid or tank to tank so you will have to experiment a bit)
I dont think that this is possible in unity. Maybe there are some Assets that offer something like this.
But you could create a similar effect with Blender.
Check out Morphing Shape Animations.
There are some cool tutorials out there Morphing Shape Animations in Blender
Related
I recently started having a look at game development with Unity and was trying to make a simple 2D character with basic movement abilities. This character is supposed to jump and move from side to side, but only if it is standing on something.
Now my question is: How do you check if a player is standing on something? / Get the distance to the next game object / collider beneath the player game object?
Would greatly apreciate any helpful answers and especially explanations on how exactly it works. Thanks!
To do this, you need to send a ray to detect the point of impact on the ground and then calculate the distance. The code below sends a ray from the center of your object down to the maximum height (3) and gives the size.
public LayerMask groundLayer;
public float maxRayLength = 3;
public void Update()
{
var hit = Physics2D.Raycast(transform.position, Vector3.down, maxRayLength, groundLayer.value);
if (hit) Debug.Log(hit.distance); // it will print current distance from pivot
}
If you want to calculate the height of the ray from the character's foot, there are two methods, one is subtracting half the height of the character from it.
Physics2D.Raycast(transform.position-transform.up*height, ....)
Next one is to use an empty object at the base of the character, which we refer to instead of the center.
public Transform pivot;
Then..
Physics2D.Raycast(pivot, ....)
There are a few ways of actually doing this.
The most usual although a bit complicated way of doing it for a beginner is using Raycasts. A Raycast is basically a small invisible line that starts and ends where you tell it to. If anything of a specific tag or layer is caught in it's crossfire you can basically pull that object from your code. Raycasts are used for a lot of things, most notably in Shooter games to shoot or in games like Skyrim to pickup objects and interact with them.
Another way to do this, which is a bit more popular in 2D games is to create a "feet" GameObject and make it the child of the player in the hierarchy. You can add a box collider on that GameObject and check the "IsTrigger". You can add a Tag to your ground objects and through your code using the OnTriggerEnter() and OnTriggerExit() Methods you can basically tell when your character is floating on air and when he is on ground.
Another popular method is to use the Physics.OverlapBox() Method which is pretty much the same as the Trigger Method but you are creating an invisible box (much like a raycast) and instead of only getting notified when Triggered (something enters or exits) you check if the invisible box is colliding with another object/tag/collider (which could be your ground).
There are also a few different things you can do with a Nav Mesh (mostly in 3D) but I think that for now these 3 should suffice!
Today my tutor was helping and explaining to me how to add animations into my game, we added wobble effects to my 4 buttons. (pink, blue, yellow, purple) We fully compelted the first button together and then he left me to do the other 3 using what he had taught me. I thought I had done it correctly beause after adding the need code to all 4 of the buttons the pink button's wobble animation works, but the other 3 don't do the animation.
I was looking through to see if something was different and in the Animation dock they come up yellow and say (Missing!) even the pink button that works has this come up. I don't know what this means or how to fix it and would appreciate if anyone could help and explain this to me! Thankyou.
{
if (Input.GetButtonDown("Horizontal"))
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
//play pink wobble animation
m_Animator.SetTrigger("Pinkhit");
}
if (Input.GetKeyDown(KeyCode.RightArrow))
{
//play purple wobble animation
m_Animator.SetTrigger("PurpleHit");
}
}
if (Input.GetButtonDown("Vertical"))
{
if (Input.GetKeyDown(KeyCode.DownArrow))
{
//play blue wobble animation
m_Animator.SetTrigger("BlueHit");
}
if (Input.GetKeyDown(KeyCode.UpArrow))
{
//play yellow wobble animation
m_Animator.SetTrigger("YellowHit");
}
}
}
The property key frames in AnimationClips are string based on the property paths which include the type names of the component and the field names they belong to.
The (!Missing) can mean e.g. the following
you removed the according MonoBehaviour from your object
you renamed your according MonoBehaviour class
you renamed the animated fields
this AnimationClip was originally for another object and now you are trying to use it for an object which doesn't have according MonoBehaviour / component attached. (which basically equals the first case)
You renamed or changed the hierarchy structure of the according child GameObject which is nested under the one with the Animator attached. (Renaming the root object would not be an issue)
therefore the according property paths that should be animated by your AnimationClip can not be found on this object.
Since the Scale belongs to Transform which is a component each and every GameObject has to have none of the upper points can be the case here and you most probably happened to rename the object like so:
This is of course a little bummer especially when working with prefabs, bu for the AnimationClips to work properly
either make sure to put the Animator directly on the object that is supposed to be animated (in that case naming is no issue)
or make sure you don't rename or change the hierarchy structure of according child objects
Basically, In my scene, underneath a GameObject called 'GameOverUI' I have some buttons and a Panel that covers the screen. I have made a simple animation where the panel's opacity (The alpha channel) increases. Do any of you know how to make it so that when the player dies, it enables GameOverUI and plays the animation for the panel once?
Edit: Forgot to mention, I know how to make it so that 'GameOverUI' is enabled, I just don't know how to make the animation play
If you are looking for a solution with animations, then here you go:
Create a script for your GameOverUI gameObject. Really simple:
public class UIHandler : MonoBehaviour
{
private void OnEnable()
{
//play "dead screen" animation
}
}
Method OnEnable() is a MonoBehavior function, and will be called when you enable a GameObject by calling myGameObject.SetActive(true);.
However, I would recommend thinking about another solution. I usually leave GameOverUI always active and use it to manage its children via script. So I think it would be more elegant to write something like this:
public class UIHandler : MonoBehaviour
{
public void PlayerDied()
{
//play "dead screen" animation
}
}
The difference is, that instead of enabling and disabling the GameObject, you call a method. This way, you will be able to pass data (as function parameters) if you need to do so. For example, you can write to the screen, what caused the death. And further on, the GameObject will be able to manage its UI components for other purposes.
I hope it makes sense and I could be of your help!
I want an enemy to look at the player when he shoots him, I call this function from an animation event:
public void ShootPlayer
{
thisTr.LookAt(playerTr);
thisTr.rotation = Quaternion.Euler(0, thisTr.rotation.eulerAngles.y, 0);
GameObject newArrow = Instantiate(straightFlightArrow, shootPoint.position, transform.rotation);
em.canMove = true;
}
It does get called, but model`s rotation does not change. The weird thing is, if I invoke thisTr.LookAt(playerTr) in Start(), the model will rotate accordingly during the shoot animation. Also, if I rotate the model from another script the same way before the shoot animation starts it will work as well.
So for some reason trying to rotate the model specifically from the animation event does not work for me. I have tried checking constraints on and off, applied and disabled root motion, but there is no effect. I am sure that there is some obvious mistake that I make, but I just can`t figure it out.
Properties that are being animated (i.e. inhibited by the animation engine) cannot be set from code. There's a workaround for it, but it's ugly - you need to do your update in LateUpdate() (so it's after the animation engine does it's transformations) and you have to keep track of the updated value, overwriting it each and every frame (because otherwise the engine will overwrite your next frame with what it had calculated).
Other workarounds involve wrapping GameObjects in empty GameObjects, i.e. my animator animated an object's position, which I wanted to change in code as well, so my structure was:
animatedContainer
|- actualObjectAlsoAnimatedFromCode
As far as I know this also applies to properties which are inhibited at some point, but not necessarily changed during current animation (and I think this is the issue your case is facing).
Now when the player is aiming he can't walk. I need to make it stop aiming to be able to keep walking. I'm using the mouse right button for aiming with aiming parameter false/true.
And i created a blend tree there i mixed between Walk and Idle.
But now i want also to mix between Walk and Aiming.
And when i make double click on Movement there the blend tree:
So now i can walk and when i stop walking with the keys it's idling.
I can also use the mouse right button for aiming one click on the mouse right button will keep aiming another click will stop aiming.
But when i'm in the aiming state i can't walk.
The question is how do i mix the Walk with the Aiming (The aiming animation i have is called: Rifle_Aiming_Idle there is also animation called Rifle_Aiming_Walk_F) ?
This animations are not my own. But i wonder if i should mix the aiming_Idle with the Walk(HumanoidWalk i have already in the blend tree or to use somehow only with the Rifle_Aiming_Walk_F somehow).
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Soldier : MonoBehaviour
{
private Animator anim;
private void Start()
{
anim = GetComponent<Animator>();
}
void Update()
{
var inputVelx = Input.GetAxis("Horizontal");
var inputVely = Input.GetAxis("Vertical");
transform.Rotate(0, inputVelx, 0);
anim.SetFloat("VelX", inputVelx);
anim.SetFloat("VelY", inputVely);
if (Input.GetMouseButtonDown(1))
{
anim.SetBool("Aiming", !anim.GetBool("Aiming"));
}
}
}
There is a short video clip in youtube the owner of this package he made showing the movements too of the aiming/s. I'm not sure just how to make that the character will walk and aiming at the same time:
Sci Fi Space Soldier - PolygonR
You'll need to create multiple Layers in the animator controller.
Then add Avatar mask. Please take a look at here:
http://www.theappguruz.com/blog/how-to-animate-specific-body-parts-using-avatar-mask-in-unity
As a solution you can duplicate your shoot animation and rename it as shoot_walking then animate it.
Also check it:
https://docs.unity3d.com/ScriptReference/AnimationState.AddMixingTransform.html