I've added a cube object with position (0, 0, 0) and sphere object with position (0.5, 0, -3). I've added textures and materials.
I want to move the sphere behind of all other objects with render queue or different solution.
I've added this script on the sphere. It's not working:
using UnityEngine;
public class RenderQueueTest : MonoBehaviour
{
public int renderQueuePosition = -1;
void Start()
{
GetComponent<Renderer>().material.renderQueue = renderQueuePosition;
}
}
I've also tried to change the sphere material render queue in the inspector.
Default render queue of the sphere material is: 2000
I changed it to: 1999
Doesn't work.
Here are the textures:
What you could do is try to move the sprite itself back, set the Transform position.y to -0.1 in the inspector or do it with a script like this:
using UnityEngine;
public class SendBackScrpt: MonoBehaviour
{
private Vector3 sendBack = new Vector3(0, -0.1f, 0);
private void Start()
{
Vector3 prevPos = transform.position;
transform.position = prevPos + sendBack;
}
}
what you could also try is putting the sprite above the other one in the hierarchy.
Related
I am trying to get my Spawner.cs script to work in Unity on a flappy bird game I am making. I am following this tutorial.
For some reason only one set of pipes will cross the screen and none others appear. I am a beginner and appreciate any help in this matter. Here is the code for the Spawner.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class spawner : MonoBehaviour
{
public float queueTime = 1.5f;
private float time = 0;
public GameObject ObstaclePipes;
public float height;
void Start () {
GameObject newpipe = Instantiate(ObstaclePipes);
newpipe.transform.position = transform.position + new Vector3(0, Random.Range(-height, height), 0);
}
// Update is called once per frame
void Update()
{
if(time > queueTime)
{
GameObject go = Instantiate(ObstaclePipes);
go.transform.position = transform.position + new Vector3(0, Random.Range(-height, height), 0);
time = 0;
Destroy(go, 10);
}
time += Time.deltaTime;
}
}
Here is the code for the obstacles.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class obstacles : MonoBehaviour
{
// Start is called before the first frame update
public float speed;
// Update is called once per frame
void Update()
{
transform.position += ((Vector3.left * speed) * Time.deltaTime);
}
}
Given that the obstacles are spawning and not visible on the screen, the obstacle sprite renderers are rendered behind the background. This behavior is common when working with 2D games. To solve this, we have to use sorting layers.
Sorting layer allows us to set the render order of sprites. In your case, we have to set the order of sorting layer for your obstacles so that they spawn in front of the background instead of behind it.
Hence in the sprite renderer component of the obstacle, set its Order In Layer to a value more than 0 as 0 is the default value which was the same for both background and obstacle. In our case, let's set it to 1. Now, the obstacles are rendered first, and then the background which lets us see the obstacles on the screen.
As the title says, I have a scene with three objects, a cube, a sphere, and a cylinder-like you can see in the image below.
What I'm trying to achieve is that when I press the "Rotate" button, the three objects rotate in an anti-clockwise direction, so the cylinder goes where the cube was, the cube goes where the sphere was, and the sphere goes where the cylinder was. If I click the button again, they rotate once again and so on. So far, I managed to make them rotate around an empty object at the center of the "triangle" they form with their initial position.
This is what happens when I first click the "Rotate" button:
As you can see, the object rotates, but they don't keep the same coordinate of the object that was previously in that position, so I was thinking of having them exchange coordinates. How can I achieve that or making them rotate how I want to?
Here is the code I wrote so far:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class RotateObject : MonoBehaviour {
//rotating objects
[SerializeField]
private GameObject cube;
[SerializeField]
private GameObject sphere;
[SerializeField]
private GameObject cylinder;
private Renderer cubeRenderer;
private Renderer sphereRenderer;
private Renderer cylinderRenderer;
//rotation target
public GameObject target;
private void Start() {
cubeRenderer = cube.GetComponent<Renderer>();
sphereRenderer = sphere.GetComponent<Renderer>();
cylinderRenderer = cylinder.GetComponent<Renderer>();
gameObject.GetComponent<Button>().onClick.AddListener(Rotate);
}
void Rotate() {
//rotate objects by 120 degrees
cube.transform.RotateAround(target.transform.position, Vector3.up, -120);
sphere.transform.RotateAround(target.transform.position, Vector3.up, -120);
cylinder.transform.RotateAround(target.transform.position, Vector3.up, -120);
}
}
Thanks in advance for helping me!
The easiest way to make an object(s) rotate around a point is to have it/them as a child of the point then rotate the point itself.
Object Hierarchy
Rotator Script to be put on the parent object:
public class RotateObjects : MonoBehaviour
{
[SerializeField] Button rotateButton;
// Start is called before the first frame update
void Start()
{
rotateButton.onClick.RemoveAllListeners();
rotateButton.onClick.AddListener(RotateClockwise);
}
void RotateClockwise()
{
float newRotation = (360 / transform.childCount);
transform.Rotate(new Vector3(0, newRotation, 0));
}
}
You are rotating around an object. Like the earth rotates around the sun; that means it will change its position. Use
transform.rotation = new Quaternion(rotx, roty, rotz, rotw);
or
transform.Rotate(rotx, roty, rotz);
Instead of rotating about a point rotate the shape, it's self.
I am trying to set up control of Player game object by UI buttons.
2d top down view scene.
I want to transfer Player object smoothly on fixed distance (0.8 for Axix X for left-right direction and 2.4 for up-down)when I release left/right/up/down ui buttons.
Here i found code for smooth movement but there Player is moving all the time while ui button is pressed.
Can you help me to make it move on mouse up (pointer up) and to move for public x= 0.8f for left/right, and public y = 2.4f for up/down
And at the same time i want to use different speed (peblic) for moves on x and y Axis
Its ok if it should be totally other script using smth like transform.translate
Kindly guide to for any possible solution for this. Thanks
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
public class PlayerControl : MonoBehaviour
{
float movX;
float movY;
Rigidbody2D rb;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
movX = CrossPlatformInputManager.GetAxisRaw("Horizontal");
movY = CrossPlatformInputManager.GetAxisRaw("Vertical");
rb.velocity = new Vector2(movX * 1, movY * 1);
}
}
This script can be moved by the WASD keys.
This should move your gameObject by the requested amount over x amount of time(speed).
Currently it can be only moved when it'S reached its destionation but you can easily modify this :), by stopping the coroutine
using System.Collections;
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
// We gonna move by WASD keys
[Header("Speed & Movement settings")]
[SerializeField]
float Speed = 2.0f;
[SerializeField]
float movSpeedX = 0.8f;
[SerializeField]
float movSpeedY = 2.4f;
bool ReachedTarget = true;
void Update()
{
if (ReachedTarget)
{
Vector2 dest = Vector2.zero;
Vector2 currentPos = transform.position;
if (Input.GetKeyUp(KeyCode.W))
{
dest = currentPos + (Vector2.up * movSpeedY);
StartCoroutine(moveTo(dest, Speed));
}
else if (Input.GetKeyUp(KeyCode.S))
{
dest = currentPos + (Vector2.down * movSpeedY);
StartCoroutine(moveTo(dest, Speed));
}
else if (Input.GetKeyUp(KeyCode.D))
{
dest = currentPos + (Vector2.right * movSpeedX);
StartCoroutine(moveTo(dest, Speed));
}
else if (Input.GetKeyUp(KeyCode.A))
{
dest = currentPos + (Vector2.left * movSpeedX);
StartCoroutine(moveTo(dest, Speed));
}
}
}
// Time to take is in seconds
IEnumerator moveTo(Vector2 TargetPosition, float TimetoTake)
{
Vector2 originalPosition = transform.position;
float Time_taken = 0f;
ReachedTarget = false;
while (Time_taken < 1)
{
Time_taken += Time.deltaTime / TimetoTake;
// Interpolating between the original and target position this basically provides your "speed"
transform.position = Vector2.Lerp(originalPosition, TargetPosition, Time_taken);
yield return null;
}
Time_taken = 0;
transform.position = TargetPosition;
ReachedTarget = true;
}
}
I can't find any documentation of CrossPlatformInputManager, and I know nothing about it. But if you need to get the event of "release a key" instead of "press the key", try this: Input.GetKeyUp.
Description
Returns true during the frame the user releases the key identified by
name.
You need to call this function from the Update function, since the
state gets reset each frame. It will not return true until the user
has pressed the key and released it again.
For the list of key identifiers see Conventional Game Input. When
dealing with input it is recommended to use Input.GetAxis and
Input.GetButton instead since it allows end-users to configure the
keys.
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
void Update()
{
if (Input.GetKeyUp("space"))
{
print("Space key was released");
}
}
}
If you want to stop the rigid body, you need to reset its velocity to
zero. Or you can use
Rigidbody2D.MovePosition
to move it a certain distance.
Parameters
position The new position for the Rigidbody object.
Description
Moves the rigidbody to position.
Moves the rigidbody to the specified position by calculating the
appropriate linear velocity required to move the rigidbody to that
position during the next physics update. During the move, neither
gravity or linear drag will affect the body. This causes the object to
rapidly move from the existing position, through the world, to the
specified position.
Because this feature allows a rigidbody to be moved rapidly to the
specified position through the world, any colliders attached to the
rigidbody will react as expected i.e. they will produce collisions
and/or triggers. This also means that if the colliders produce a
collision then it will affect the rigidbody movement and potentially
stop it from reaching the specified position during the next physics
update. If the rigidbody is kinematic then any collisions won't affect
the rigidbody itself and will only affect any other dynamic colliders.
2D rigidbodies have a fixed limit on how fast they can move therefore
attempting to move large distances over short time-scales can result
in the rigidbody not reaching the specified position during the next
physics update. It is recommended that you use this for relatively
small distance movements only.
It is important to understand that the actual position change will
only occur during the next physics update therefore calling this
method repeatedly without waiting for the next physics update will
result in the last call being used. For this reason, it is recommended
that it is called during the FixedUpdate callback.
Note: MovePosition is intended for use with kinematic rigidbodies.
// Move sprite bottom left to upper right. It does not stop moving.
// The Rigidbody2D gives the position for the cube.
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour
{
public Texture2D tex;
private Vector2 velocity;
private Rigidbody2D rb2D;
private Sprite mySprite;
private SpriteRenderer sr;
void Awake()
{
sr = gameObject.AddComponent<SpriteRenderer>();
rb2D = gameObject.AddComponent<Rigidbody2D>();
}
void Start()
{
mySprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), new Vector2(0.5f, 0.5f), 100.0f);
velocity = new Vector2(1.75f, 1.1f);
sr.color = new Color(0.9f, 0.9f, 0.0f, 1.0f);
transform.position = new Vector3(-2.0f, -2.0f, 0.0f);
sr.sprite = mySprite;
}
void FixedUpdate()
{
rb2D.MovePosition(rb2D.position + velocity * Time.fixedDeltaTime);
}
}
Both documents have an example.
Or you don't want to user keyboard but UI buttons, try this: IPointerDownHandler and IPointerUpHandler
Description
Interface to implement if you wish to receive OnPointerDown callbacks.
Detects ongoing mouse clicks until release of the mouse button. Use
IPointerUpHandler to handle the release of the mouse button.
//Attach this script to the GameObject you would like to have mouse clicks detected on
//This script outputs a message to the Console when a click is currently detected or when it is released on the GameObject with this script attached
using UnityEngine;
using UnityEngine.EventSystems;
public class Example : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
//Detect current clicks on the GameObject (the one with the script attached)
public void OnPointerDown(PointerEventData pointerEventData)
{
//Output the name of the GameObject that is being clicked
Debug.Log(name + "Game Object Click in Progress");
}
//Detect if clicks are no longer registering
public void OnPointerUp(PointerEventData pointerEventData)
{
Debug.Log(name + "No longer being clicked");
}
}
I can't manage to instantiate a prefab at my mouse position.
I've tried to instantiate the prefab at the current mouse position, but on click, the block shows in the hierarchy and not the scene. It also creates 4-5 prefabs.
using UnityEngine;
public class Building : MonoBehaviour
{
public GameObject block;
void Update()
{
if (Input.GetMouseButton(0))
{
Instantiate(block, new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0f), Quaternion.identity);
}
}
}
I want to create 1 prefab of the block, and I want it to show up in the scene view.
Input.mousePosition is the coordinates of the mouse on the screen. Use Camera.ScreenToViewportPoint to get the world position.
The block will not show in the scene, because its position is likely something like (500, 300, 0), which is very far. Select the block in the Hierarchy and press "F" to see it.
Input.GetMouseButton() keeps firing as long as the mouse is held. Change this to Imput.GetMouseButtonDown()
using UnityEngine;
public class Building : MonoBehaviour {
public GameObject block;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition);
Instantiate(block, pos, Quaternion.identity);
}
}
}
You need to convert from screen space to world space.
One way to do this is to use Camera.ScreenToWorldPoint:
private Camera mainCam;
void Start()
{
mainCam = Camera.main;
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector3 blockPos = mainCam.ScreenToWorldPoint(Input.mousePosition);
Instantiate(block, blockPos, 0f), Quaternion.identity);
}
}
If you want to spawn further away from the camera, look into Camera.ScreenPointToRay.
The droid have a box collider also the door have a box collider.
But when i move the character(FPSController/FirstPersoncharacter) the player the character stop can't move through the door but the droid can.
I tried to turn off/on the Is Trigger property on the droid box collider but it didn't change.
I want the droid to act like the player when colliding with other objects like the droid is part of the player.
The only code i'm using is attached to the FirstPersonCharacter:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DroidMove : MonoBehaviour
{
public GameObject droid;
private float distance;
private Camera cam;
private void Start()
{
cam = GetComponent<Camera>();
distance = Vector3.Distance(cam.transform.position, droid.transform.position);
droid.SetActive(false);
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.F))
{
droid.SetActive(!droid.activeInHierarchy);
}
}
}
I tried to add a Rigidbody component to the droid to the NAVI or to the Droid_Player but it didn't solve it. I don't have any other code that handle collidings.
UPDATE to what i tried and did so far:
From the NAVI (Droid) i removed the box collider component and added two things:
Character Controller component
Control script (This script is coming with the NAVI(Droid))
This is the Control script:
using UnityEngine;
using System.Collections;
public class Control : MonoBehaviour
{
public float rotationDamping = 20f;
public float speed = 10f;
public int gravity = 0;
public Animator animator;
float verticalVel; // Used for continuing momentum while in air
CharacterController controller;
void Start()
{
controller = (CharacterController)GetComponent(typeof(CharacterController));
}
float UpdateMovement()
{
// Movement
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 inputVec = new Vector3(x, 0, z);
inputVec *= speed;
controller.Move((inputVec + Vector3.up * -gravity + new Vector3(0, verticalVel, 0)) * Time.deltaTime);
// Rotation
if (inputVec != Vector3.zero)
transform.rotation = Quaternion.Slerp(transform.rotation,
Quaternion.LookRotation(inputVec),
Time.deltaTime * rotationDamping);
return inputVec.magnitude;
}
void AnimationControl ()
{
if(Input.GetKey("a") || Input.GetKey("s") || Input.GetKey("d") || Input.GetKey("w"))
{
animator.SetBool ("Moving" , true);
}
else
{
animator.SetBool ("Moving" , false);
}
if(Input.GetKey("space"))
{
animator.SetBool ("Angry" , true);
}
else
{
animator.SetBool ("Angry" , false);
}
if(Input.GetKey("mouse 0"))
{
animator.SetBool ("Scared" , true);
}
else
{
animator.SetBool ("Scared" , false);
}
}
void Update()
{
UpdateMovement();
AnimationControl();
if ( controller.isGrounded )
verticalVel = 0f;// Remove any persistent velocity after landing
}
}
Now when i move the character close to a door or wall also the NAVI(Droid) stop and is not moving through the door or wall and this is fine. But now i have another problem. If i will keep moving to the door or wall it looks like the character is moving over/on the NAVI Droid.
The Navi droid is not changing position.
In this screenshot is how it looks like when i moved close to the door the collider on the door and the NAVI Droid are working and the navi droid can't move through the door:
In this screenshot you can see what is happened when i kept moving the character to the door. On the top screen view the NAVI droid is in the same position but on the Game View on the bottom it seems like the character is moving over/on the NAVI droid.
And if i will keep moving to the door the character will not move but the droid looks like pushed back or the character will keep moving over the droid.
This is a short video clip i recorded showing the problem.
The problem start at second 20:
Collider problem
I tried to add box collider to the droid tried rigidbody nothing worked only this script and component but now i have this problem in the video.
Looks like your droid probably needs a RigidBody component.
If that doesn't solve it, you should add some relevant code snippets to your question to show how/where you've tried to detect and handle collisions.