So, i'm rather new to unity and I have a problem. I have a game object that has a movement/animation script and I want the character to get smaller while it moves on Pos Y. I tried using a parent/child configuration where the script for scaling is on the parent and the sprite renderer, animator, rigid body, movement, basically everything else is on the child. It animates it but it doesn't scale it, how can I fix this?
Here are my scripts:
Scaling player:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScalingCamera : MonoBehaviour
{
// Start is called before the first frame update
public float minY = 290f;
public float maxY = 320f;
public float minScale = 0.5f;
public float maxScale = 2.0f;
private Transform childTransform;
private SpriteRenderer childSpriteRenderer;
private void Start()
{
childTransform = transform.GetChild(0);
// Check if the child exists
if (childTransform != null)
{
// Check if the child has a SpriteRenderer component
childSpriteRenderer = childTransform.GetComponent<SpriteRenderer>();
if (childSpriteRenderer == null)
{
Debug.LogError("Child does not have a SpriteRenderer component.");
}
}
else
{
Debug.LogError("No child found for scaling.");
}
}
private void LateUpdate()
{
// Get the Y position of the character
float yPos = transform.position.y;
// Clamp the Y position within the specified range
yPos = Mathf.Clamp(yPos, minY, maxY);
// Calculate the scale based on the clamped Y position
float scale = Mathf.Lerp(minScale, maxScale, Mathf.InverseLerp(minY, maxY, yPos));
// Apply the scale to the child GameObject
childTransform.localScale = new Vector3(scale, scale, 1f);
// Optionally, apply the scale to the child's SpriteRenderer
if (childSpriteRenderer != null)
{
childSpriteRenderer.size = new Vector2(childSpriteRenderer.size.x * scale, childSpriteRenderer.size.y * scale);
}
}
}
Movement/Animation on player
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
[DebuggerDisplay("{" + nameof(GetDebuggerDisplay) + "(),nq}")]
public class movement : MonoBehaviour
{
[SerializeField] private int speed = 50;
private Vector2 move;
[SerializeField] private Animator animator;
private Rigidbody2D rb;
private void Awake()
{
rb = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
}
private void OnMovement(InputValue value)
{
move = value.Get<Vector2>();
if (move.x != 0 || move.y != 0)
{
animator.SetFloat("X", move.x);
animator.SetFloat("Y", move.y);
animator.SetBool("IsWalking", true);
}
else
animator.SetBool("IsWalking", false);
}
private void FixedUpdate()
{
rb.MovePosition(rb.position + move * speed * Time.fixedDeltaTime);
}
private string GetDebuggerDisplay()
{
return ToString();
}
}
And a ss of my unity hierarchy:
I've tried switching them around, one time the animator works, the other the scaling but never both. I checked the Script execution order, the scaling is after the animation. It has all the right tags, it doesnt have any colliders (it used to but that wasn't the problem). I also added debuggers all around and it says that it's scaling it on all steps but i don't see any difference (no, the object is big enough to see clear difference when it moves).
Any help would be appreciated !!
Like you already found out, you have the Rigidbody2D on the child GameObject, so only the child will move. You said you already tried putting the movement script and the Rigidbody2D onto the parent. That should work. Try to make sure that...
Also, on a side note, for learning purposes:
If you want to ensure that your ScalingCamera script has a SpriteRenderer (I think you shouldn't in this case, though, as you don't need the SpriteRenderer for the logic to work), you can add the attribute [RequireComponent(typeof(SpriteRenderer))] above your class name, like so:
The scaling does not have to happen after updating the Animator per se. So you do not need to use LateUpdate and can use a regular Update method instead.
Changing the SpriteRenderer.size does not do anything for regular sprites. It only affects the sprite if the sprite has a Tiled or Sliced draw mode. So you can remove that code.
It seems like you are creating your game entirely in the UI. This is not good practice. Don't worry about it now, but something to keep in mind for your next game :)