I created a new animation for meteor GameObject , the animation functions in first scene normally, but the second scene is not playing regularly:
video explanation of the problem
I think the reason for this problem is timeScale , and I added this code from meteor object:
void Start()
{
Time.timeScale = 1f;
}
The problem is not fixed by this.
Animations are triggered by setting the value of an Animator object.
I.E.
[SerializeField] Animator anim;
void SetFields()
{
anim.SetBool("flagName", true);
anim.SetFloat("flagName", 0);
anim.SetInteger("flagName", 0);
}
In your first screen, you must have some script that is setting the field of your meteor animator which has not been added to your new scene
Related
I have created a player prefab (called Tim in my project) and am trying to make all the references to gameObjects and transforms directly from the one of the players scripts which is actually attached to a gun object which is a child of the player prefab.
The issue is I cant manage to reference the camera in the script although I've looked and tried many different methods, none of them seemed to work. Unity prints this error in the console though : "NullReferenceException: Object reference not set to an instance of an object". And here is the script :
public class Gun_Control : MonoBehaviour
{
// References for GameObjects
[SerializeField] private Rigidbody2D rb;
private GameObject Player;
[SerializeField] private Transform PlayerTransform;
private GameObject Gun;
[SerializeField] private Transform GunTransform;
private Camera MainCamera;
private GameObject firePoint;
[SerializeField] private Transform firePointTransform;
[SerializeField] private GameObject bulletPrefab;
// Variables for Shooting
private Vector2 mousePos;
private float bulletForce = 20f;
// Start is called at the beginning
void Start()
{
Debug.Log("Starting");
Player = GameObject.FindWithTag("Player");
PlayerTransform = Player.transform;
Gun = GameObject.FindWithTag("PlayerGun");
GunTransform = Gun.transform;
MainCamera = GameObject.FindWithTag("Camera").GetComponent<Camera>();
firePoint = GameObject.FindWithTag("PlayerFirePoint");
firePointTransform = firePoint.transform;
}
// Update is called once per frame
void Update()
{
// Get mouse position
mousePos = MainCamera.ScreenToWorldPoint(Input.mousePosition);
// Run shoot function on left click
if(Input.GetButtonDown("Fire1"))
{
Shoot();
}
}
// Update is called on every physics frame
void FixedUpdate()
{
// Set gun position to player position
GunTransform.position = PlayerTransform.position;
// Set gun rotation to mouse position
Vector2 lookDir = mousePos - rb.position;
float angle = Mathf.Atan2(lookDir.y ,lookDir.x) * Mathf.Rad2Deg - 180f;
rb.rotation = angle;
}
void Shoot()
{
// Instantiate a bullet at the firepoint and give it force
GameObject bullet = Instantiate(bulletPrefab, firePointTransform.position, firePointTransform.rotation);
Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
rb.AddForce(firePointTransform.up * bulletForce, ForceMode2D.Impulse);
}
}
Right now I have a variable, MainCamera, and when the script starts I look for a camera which has "Camera" as its tag which is set correctly.
I can add on if anyone needs more details and thank you to everyone for taking the time to help.
Edit 1 :
I tried what thunderkill suggested but it doesnt seem to work.
Here is a picture of the new code.
And when I try to use Debug.Log(Camera.main); it prints null.
here is a good example to access your main camera :
Camera m_MainCamera;
void Start()
{
//This gets the Main Camera from the Scene
if(Camera.main != null){
m_MainCamera = Camera.main;
//This enables Main Camera
m_MainCamera.enabled = true;
}
}
Camera c = Camera.main;//get the camera Tagged "MainCamera"
So you have to Check if your Camera tag is "MainCamera".
or you try :
GameObject.FindObjectOfType<Camera>();
(I don't recommend the second solution)
So I ended up finding the answer.I just deleted the camera in my scene and created a new one and then ended up using : MainCamera = GameObject.FindWithTag("Camera").GetComponent<Camera>(); which worked this time. The issue could have also been caused by errors present before in my code.
I'm doing a platformer game with Unity 2D and I wanted to flip the character sprite left when the player move him left, but for some reasons it doesn't work. I tried to make this one script:
transform.rotation = new Vector3(0f, 180f, 0f);
but it didn't work. So then I wrote this:
transform.localScale = new Vector3(-0.35f, 0.35f, 1f); //the player's scale x and y are 0.35 by default
but it didn't work too. Then I found this error message in the console: NullReferenceException: Object reference not set to an instance of an object
UnityEditor.Graphs.Edge.WakeUp () (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Edge.cs:114).
What should I do? I'm doing this game for a game jam so I need to resolve this problem quickly. Thank you.
EDIT: I noticed that I can flip the sprite in the editor, but that I can't do that using scripts.
From this thread I found, it seems like an old bug from Unity's UnityEditor.Graphs.DLL code.
Try restarting Unity completely.
This bug seems to occur only in the editor, and not after a game is built, so you should be safe.
I haven't worked on any 2D Unity projects in a while but here is a piece of code I used to resolve that issue in the past. Let me know if it helps.
private void FlipSprite()
{
bool playerHasHorizontalSpeed = Mathf.Abs(myRigidBody.velocity.x) > Mathf.Epsilon;
if(playerHasHorizontalSpeed)
{
transform.localScale = new Vector2(Mathf.Sign(myRigidBody.velocity.x), 1f);
}
}
This is a bit old so be sure to let me know how this works. You'll need to finish the rest of the controls, but this should work.
public class SpriteFlipper : MonoBehaviour
{
// variable to hold a reference to our SpriteRenderer component
private SpriteRenderer mySpriteRenderer;
// This function is called just one time by Unity the moment the component loads
private void Awake()
{
// get a reference to the SpriteRenderer component on this gameObject
mySpriteRenderer = GetComponent<SpriteRenderer>();
}
// This function is called by Unity every frame the component is enabled
private void Update()
{
// if the A key was pressed this frame
if(Input.GetKeyDown(KeyCode.A))
{
// if the variable isn't empty (we have a reference to our SpriteRenderer
if(mySpriteRenderer != null)
{
// flip the sprite
mySpriteRenderer.flipX = true;
}
}
}
}
I'm creating shooting in Unity, I've set up everything but the problem is that I want the animation to play only on single click but in my script it plays animation infinitely while holding the button. Check the script below. Thanks.
public GameObject bulletPrefab;
public Transform firePoint;
private Animator anim;
// Start is called before the first frame update
void Start()
{
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Instantiate(bulletPrefab, firePoint.position, Quaternion.identity);
anim.SetBool("isShooting", true);
}
if (Input.GetKeyUp(KeyCode.Space))
{
anim.SetBool("isShooting", false);
}
}
Set 2 States with just Keys on time = 0 the end position Shooting and the end position idle. From idle to shooting with a trigger parameter. From shooting to idle just a time transition. Ps shooting can be done with multiple frames too. Hope it helps.
I'm developing a unity game and basically, I have a prefab with a sprite inside it. I created an animation attached to that sprite.
FrogPrefab
|__ FrogSprite
I created a script with a public field "prefab" where I pass my prefab.
My question is, how can I stop and play this animation from my script.
I instantiated my prefab from my start method...
public GameObject gameCharacterPrefab;
private GameObject frog;
void start() {
frog = (GameObject)Instantiate(gameCharacterPrefab, objectPoolPosition, Quaternion.identity);
}
I'm trying to do something like that...
frog.animation.stop();
appreciate any help
First, note that the function should be called Start not start. Maybe this is a typo in the question but it's worth mentioning.
Use GetComponent to get the Animator or Animation component. If the animation is a child of the prefab then use GetComponentInChildren.
If using the Animator component:
public GameObject gameCharacterPrefab;
private GameObject frog;
Vector3 objectPoolPosition = Vector3.zero;
Animator anim;
Instantiate the prefab
frog = (GameObject)Instantiate(gameCharacterPrefab, objectPoolPosition, Quaternion.identity);
Get the Animator component
anim = frog.GetComponent<Animator>();
Play animation state
anim.Play("AnimStateName");
Stop animation
anim.StopPlayback();
If using the Animation component:
public GameObject gameCharacterPrefab;
private GameObject frog;
Vector3 objectPoolPosition = Vector3.zero;
Animation anim;
Instantiate the prefab
frog = (GameObject)Instantiate(gameCharacterPrefab, objectPoolPosition, Quaternion.identity);
Get the Animation component
anim = frog.GetComponent<Animation>();
Play animation name
anim.Play("AnimName");
Stop animation
anim.Stop();
For playing animation we can use Play() but for stopping the animation the Stop method is become obsolete in Unity 2019 or higher versions. So, For disable animation we can use enable flag and set it to false.
//For playing the animation
frog.GetComponent<Animator>().Play();
or
frog.GetComponent<Animator>().enable = true;
//For stop the animation
frog.GetComponent<Animator>().enabled = false;
I have problems accessing the enabled variable in children of my Player GameObject.
-Human holds Rigidbody2D, BoxCollider, PlayerController script and Animator
-body and range_attack_body only hold SpriteRenderer
What I want to do:
I want to change the SpriteRenderer of my Player Object when mouse button is on hold. There are SpriteRenderers in body and range_attack_body. Both GameObjects are part of animations.
body.SpriteRenderer is active and range_attack_body.SpriteRenderer inactive during normal motion.
In my PlayerController script I wrote a routine that will trigger an attack animation when mouse button is on hold. In this routine I wanted to change the enabled states of the SpriteRenderers. However nothing is happening, meaning the varibales are not changing during runtime. I already checked if the GameObjects and SpriteRenderers are accessed correctly during Awake() and I can find both renderers in my SpriteRenderer array using debug messages.
On top of that I checked what happens if I add a SpriteRenderer to my Human GameObject. It will appear in my SpriteRenderer array and I have full access to enabled variable meaning I can change them in my routine. So I figured there might be a conflict with body and range_attack_body due to their SpriteRenderers being part of animations. I added Human.SpriteRenderer to an animation and can still change variables.
I have no clue what is going on, please help. Here is some code:
public class PlayerController2D : PhysicsObject {
public float maxSpeed = 7f;
public float jumpTakeOffSpeed = 7f;
public float posOffset = 1;
protected bool flipSprite = false;
protected bool flipState = true;
private Animator animator;
private SpriteRenderer[] spriteRenderers;
void Awake ()
{
animator = GetComponent<Animator> ();
GameObject human = GameObject.Find("Human");
spriteRenderers = human.GetComponentsInChildren<SpriteRenderer> ();
}
protected override void Attack ()
{
if(Input.GetMouseButton(0))
{
spriteRenderers[0].enabled = false;
spriteRenderers[1].enabled = true;
Debug.LogError("Inhalt:" + spriteRenderers[0].ToString());
Debug.LogError("Inhalt:" + spriteRenderers[1].ToString());
animator.SetBool("attack", true); // boolean to start hold animation
}
else if(!Input.GetMouseButton(0))
{
spriteRenderers[0].enabled = true;
spriteRenderers[1].enabled = false;
animator.SetBool("attack", false);
}
}
}
Your script code is ok, the problem should be elsewhere.
First of all, disable the Animator component and run the script: if enabling/disabling the sprite renderers work, than you must look in the animation clips if you have the Sprite Renderer.Enabled property anywhere, most probably you'll have it - remove it so you can enable/disable the renderers only via script.
If the script still doesn't work, then the problem is elsewhere (another script which is accessing the enabled property of the renderers).
But I'd bet that you're changing the enabled property from the animation clips, which supercedes the script due to how the Unity execution order works (animations are always updated after the scripts and before rendering).