My sprite moves to the left, as it should but it stops moving and does not go offscreen, as I want it to. It's as if there is an invisible wall.
I have tried https://www.youtube.com/watch?v=YfIOPWuUjn8.
In the video, the person's sprite completely moves off the screen but mine doesn't.
public Sprite Pokemon_0;
public Sprite Pokemon_1;
void Update()
{
if (transform.position.x >= -40)
{
this.gameObject.GetComponent<SpriteRenderer>().sprite = Pokemon_0;
transform.Translate(-1f,0f,0f);
}
I am working on the sprite moving off the screen on the left, and a different sprite appearing from the right and moving to the centre of the screen. The code doesn't include anything about the second sprite but that is why I have referred to the sprite in my code.
You're telling it to only move left if (transform.position.x >= -40).
So either change your camera so that x = -40 is outside of your screen, or decrease the value in the boolean expression to something lower than -40 so that it moves further left until it stops moving, e.g.:
if (transform.position.x >= -80f)
{
transform.Translate(-1f,0f,0f);
}
Also, GetComponent is an expensive procedure, and you only need to set the sprite once, so you should create a Start method that does the sprite assignment. This way, you don't waste time every frame getting the same component and assigning the sprite that's already assigned to it.
The this.gameObject. part is redundant, so you can get rid of that part as well:
Start()
{
GetComponent<SpriteRenderer>().sprite = Pokemon_0;
}
Just adding to Ruzihm's answer, you can also try to use
if (GetComponent<Renderer>().isVisible)
{
transform.Translate(-1f,0f,0f);
}
instead of using a number such as "-40f" or "-80f", in this way you can be sure that the sprite will be off screen.
Related
I'm completely new (<1 week) to Unity, C# and game development generally. I'm starting out making a 2D isometric, grid-based CRPG and have hit a major wall with Unity's tilemaps.
I have a component which creates a tilemap tile underneath the parent GameObject using Tilemap.SetTile. As the GameObject moves around the grid, the tile should move with it and delete the previous tile. The tile can then create a moving obstacle node for pathfinding (which is working fine with static obstacles).
The problem is that the script actually does briefly work, just not for very long. If the GameObject moves along a path 'n' cells in a grid, the script will render 'n/2' cells every time the script is run, then stop working altogether. There's no error messages, freezing or anything, the tiles just aren't being drawn, and I know from logging in the console that the script is correctly tracking where the tiles should be drawn.
The obstacle script looks like this:
private void SetObstacleTile()
{
currentCell = obstacleMap.WorldToCell(transform.position);
if (currentCell != previousCell)
{
//set the new tile
obstacleMap.SetTile(currentCell, obstacleTile);
// erase previous
obstacleMap.SetTile(previousCell, null);
// save the new position for next frame
previousCell = currentCell;
Debug.Log(currentCell);
}
}
private void Update()
{
SetObstacleTile();
}
... and the movement currently looks like this:
void Update()
{
if (Vector3.Distance(transform.position, destination) > 0.01f)
transform.position = Vector3.MoveTowards(transform.position, destination, movementSpeed * Time.deltaTime);
}
My gut feeling is that it's something to do with how the Update() functions in the character movement and obstacle tiles component are interacting with each other but I don't have the experience to know how close I am to the problem. Any help with what could be causing this would be massively appreciated.
I'm trying to make a simple FPS game in Unity3d where a character cannot fall off the platform unless they jump off of it, walking off should be impossible.
I made a script for objects that are on a moving platform:
public GameObject Player;
private void OnTriggerEnter(Collider other)
{
if (other.gameObject == Player)
{
Player.transform.parent = transform;
}
}
private void OnTriggerExit(Collider other)
{
if (other.gameObject == Player)
{
Player.transform.parent = null;
}
}
And the only way I came up with to solve this problem is to create a short, invisible box collider working as a threshold, but adding it to every edge of every walking space would be a nightmare. Also I can't use nav mesh for it.
Raycasting just in front of the player pointing down and seeing if it hits the level would be one option, however it's very expensive to run this a lot.
If your level is square (other shapes will work but will require some maths), you can take note of the top left and bottom right points as your boundary points and check if your players position + walking speed per frame would be outside this boundary square. If it is, deny the move.
E.g
if((transform.position + transform.forward * walkingSpeed * time.deltatime).x > maxX || < minX || .y > maxY || .y << minY)
//Deny the move
In the same way that you use colliders to detect the ground to allow / disallow jumping, you can also use colliders to detect edges of platforms.
Add a small collider to each corner or midpoint of each side of the bottom of your player object. The player can only move in directionA if the colliders on sideA of the player are in contact with the ground. This means that as you approach a ledge, the nearest side to the ledge will lose contact with the ground, therefore preventing any more movement in that direction.
If player is jumping, then allow movement in all directions regardless of collider contact.
You will have to play around with the position of these colliders and which directions you allow movement, but this seems like a simple yet effective approach to me.
Create a prefab for the edges, everywhere there is an edge place the prefab so that the prefab is really the edge. This will ensure that the code that works is always present on an edge.
The only way I know to detect collision is through a trigger. Therefor, I have a paddle hitting the ball and a trigger to keep the score. However, for some reason the trigger paddle won't folloWhen I move up, the trigger paddle follows behind the normal paddle slightly then returns to it's initial position. Here is a picture of the paddle bar, the trigger is inside the normal paddle.
and here is the code to move the paddle, they have the same script but the trigger won't act correctly. Also note, that it says in the position bar on the right of the image for the trigger paddle that it is following the paddle. But it is not
void Start () {
dimensions = new Vector3(transform.localScale.x, transform.localScale.y, 0);
transform.localScale = new Vector3(.5f, .5f, 1);
}
// Update is alled once per frame
void Update () {
yPos = gameObject.transform.position.y + (Input.GetAxis ("Vertical") * paddleSpeed);
if(Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.S))
playerPos = new Vector3 (gameObject.transform.position.x, Mathf.Clamp(yPos, -yClamp, yClamp), 0);
gameObject.transform.position = playerPos;
}
I can't figure out why it won't work. Any help is extremely appreciated seeing as I have no help looking online and can't figure it out.
If you simply want the 'trigger paddle' to follow the position of the visible paddle then put the trigger paddle as a child of the visible paddle in the heirarchy (It looks like you've done this already). Nothing else is needed. Remove script you have assigned to make the trigger paddle move in the same way that the regular paddle does.
also, if you want to detect a collision properly then use OnCollisionEnter2D
also also, I know you most likely just want to get this working, but this can be done in a much better way. You don't need the child object at all. Just attach the BoxCollider2D component to the visible paddle and detect the collision from there.
I am creating a simple routine that performs an action when a GameObject falls below the bottom of a sprite. I've figured out how to get the dimensions of the sprite using bounds, but when I calculate where I think the bottom of the sprite is, it's returning a smaller number than I'd expect.
My method is as follows (the position of the sprite, minus the size of the bounds (half the width), should give me the bottom of the sprite?):
public class FooBehaviour : MonoBehaviour
{
public SpriteRenderer ChildSprite;
void Start()
{
float bottomEdgeInLocalSpace =
ChildSprite.gameObject.transform.localPosition.y - ChildSprite.bounds.extents.y;
}
}
So it turns out that Renderer.bounds is in world space, and I was working in local space, so directly applying it to the local position was giving me my nonsensical result.
By converting bounds.min to local space using InverseTransformPoint, I was able to get the expected bottom of the sprite using the following:
float position = transform.InverseTransformPoint(symbol.bounds.min).y;
I have made a thing in unity2d where an object moves according to the location of the mouse compared to the location of the object, to do this there is a vector going from the object to the mouse, all movement is either parrallel to this or perpendicular to it.
This worked fine before adding rotation of the sprite (added as shown below)
void RoterModMus()
{
fRotationIGrader = Vector2.Angle (Vector2.up, vVectorToMouse.normalized);
if(vVectorToMouse.normalized.x<0)
{
transform.rotation =Quaternion.Euler(0, 0, fRotationIGrader);
}
else{transform.rotation =Quaternion.Euler(0, 0, -fRotationIGrader); }
}
When i stop running this funtion in update the movement works again.
Is there a way to either rotate the sprite without rotating the object, or to make this not hurt movement??
I havn't been able to find anything on any of those questions, and i cant figure it out (sorry for danish code)
The code checks the angle between up and the mouse (up is zero in unity) and sets the rotation of the object to that or minus that
Awwkaw
One solution is to add an empty gameObject with the sprite component as a child to your object and then rotate the child AKA empty gameObject with sprite.