I have a script that deletes a cube primitive and then creates a new sphere primitive. How would I then move that sphere primitive?
void OnCollisionEnter(Collision collision)
{
if (collision.collider.gameObject.tag != "Destroy")
{
GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
sphere.transform.SetPositionAndRotation(gameObject.transform.position, gameObject.transform.rotation);
Destroy (gameObject);
}
}
Here is how I would do it.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Main : MonoBehaviour
{
public GameObject sphere;
private bool spawnSphere = false;
private GameObject sphereThatIWantToMove;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (spawnSphere)
{
sphereThatIWantToMove = Instantiate(sphere, new Vector3(0, 0, 0), Quaternion.identity);
spawnSphere = false;
}
//Code that moves the sphere
}
}
In my code I added a public GameObject, so that I could load a sphere prefab to it.
Then you instantiate that prefab, but store the instance in another GameObject variable, then you can just use GameObject.Transform.Position to move it around.
Some more detail on actually moving the sphere:
float x = sphereThatIWantToMove.transform.position.x;
float y = sphereThatIWantToMove.transform.position.y;
float z = sphereThatIWantToMove.transform.position.z;
if (Input.GetKeyDown(KeyCode.UpArrow))
{
y--;
}
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
x--;
}
if (Input.GetKeyDown(KeyCode.DownArrow))
{
y++;
}
if (Input.GetKeyDown(KeyCode.RightArrow))
{
x++;
}
if (Input.GetKeyDown(KeyCode.PageUp))
{
z--;
}
if (Input.GetKeyDown(KeyCode.PageDown))
{
z++;
}
sphereThatIWantToMove.transform.position = new Vector3(x, y, z);
The GameObject's coordinates are stored as a Vector3 in Transform.Position. You cannot edit that value directly, instead you have to break the values out (they're floats) using GameObject.Transform.Position.x, GameObject.Transform.Position.y, and GameObject.Transform.Position.z. Then you change those values and load them back in with a "new Vector3"
I hope that helps!
Related
I was making a platform that bounces the player after a certain period of time when the player touches it. I attached this code component to the GameObject, which is a tilemap, and it doesn't work properly. What's wrong with my code? The code and scriptable object are as follows.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ExplosionPlatform : PlatformBase
{
public float explosionPower = 20f;
public float waitTime = 1.5f;
public float colTime = 0f;
public bool isDamageOnce = false;
public Vector2 area = new Vector2(2, 2);
public Vector2 positionModify = new Vector2(1, 0);
private void OnCollisionEnter2D(Collision2D collision)
{
StartCoroutine(Explosion());
}
private IEnumerator Explosion()
{
Debug.Log("ASDF");
yield return new WaitForSeconds(waitTime);
Collider2D[] player = Physics2D.OverlapBoxAll(transform.position + (Vector3)positionModify, area, 0);
foreach (Collider2D col in player)
{
if (col.CompareTag("Player"))
{
col.gameObject.GetComponent<Rigidbody2D>().AddForce(Vector2.up * explosionPower, ForceMode2D.Impulse);
Damage();
isDamageOnce = true;
yield return new WaitForSeconds(3f);
isDamageOnce = false;
}
}
}
private void OnDrawGizmos()
{
Gizmos.color = Color.blue;
Gizmos.DrawWireCube(transform.position + (Vector3)positionModify, area);
}
}
I have confirmed that the code below works properly on GameObject, which is Unity 2d Sprite. Is there any way to use that code while using the tile map?
I did it many times,but maybe i forgot.I am trying to instantiate prefab,and scale it down but it doesnt take any effects.It only works if I scale original prefab,but then I am not able to Destroy this prefab.
public class PozicijaButona : MonoBehaviour
{
Vector2 pozicijaV;
float x, y;
Text tekstPozicije;
List<Vector2> lista = new List<Vector2>();
List<Sprite> slike1t, slike2t, slike3t, slike4t;
public GameObject instantacija;
private GameObject oznacenaSl;
Vector3 skala;
// Start is called before the first frame update
void Start()
{
tekstPozicije = GameObject.Find("Canvas/pozicija").GetComponent<Text>();
List<Vector2> lista = new List<Vector2>();
slike1t= new List<Sprite>();
for (int i = 0; i < HintoviMale.slikeT.Count; i++)
{
slike1t.Add(HintoviMale.slikeT[i]);
}
skala = transform.localScale;
instantacija.transform.localScale = skala;
Debug.Log("sjaa" + skala);
}
// Update is called once per frame
void Update()
{
}
private void OnMouseDown()
{
pozicijaV = transform.position;
x = transform.position.x;
y = transform.position.y;
string xT = x.ToString();
string yT = y.ToString();
// tekstPozicije.text=xT+","+yT;
tekstPozicije.text = pozicijaV.ToString();
Destroy(oznacenaSl);
}
public void klikNaPoziciju()
{
Debug.Log("broj itema u slici"+HintoviMale.slikeT.Count);
oznacenaSl = Instantiate (instantacija, new Vector2(-0.7f, -3.4f), Quaternion.identity);
// oznacenaSl.transform.localScale = skala;
oznacenaSl.GetComponent<SpriteRenderer>().sprite=HintoviMale.slikeT[0];
}
}
I did it many times,but maybe i forgot.I am trying to instantiate prefab,and scale it down but it doesnt take any effects.It only works if I scale original prefab,but then I am not able to Destroy this prefab.
You never call your function named "klikNaPoziciju", which contains the Instantiate call. You also have commented out the line that changes the localScale of the object named "oznacenaSl".
Here is a simple example of instantiating an object and modifying it's localScale:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InstantiateObjectExample : MonoBehaviour
{
public GameObject objectToInstantiate;
private GameObject instantiatedObject;
private void Awake()
{
CreateInstanceOfObject();
}
private void CreateInstanceOfObject()
{
instantiatedObject = Instantiate(objectToInstantiate, transform.position, Quaternion.identity);
instantiatedObject.transform.localScale = new Vector3(2f, 2f, 1f);
}
}
In the Unity Hierarchy, create an empty gameObject and attach the script to it. Then in the Inspector for the gameObject you just created, drag your prefab into the "Object to Instantiate" field.
EDIT:
OP mentioned they are calling their public method from an OnClick method in the Unity Editor. I'm not familiar with that approach, but another approach would be to use the OnMouseDown() function in your script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InstantiateObjectExample : MonoBehaviour
{
public GameObject objectToInstantiate;
private GameObject instantiatedObject;
private void OnMouseDown()
{
CreateInstanceOfObject();
}
private void CreateInstanceOfObject()
{
Debug.Log("Creating instance!");
instantiatedObject = Instantiate(objectToInstantiate, transform.position, Quaternion.identity);
instantiatedObject.transform.localScale = transform.localScale;
}
}
For this to work, make sure the object you attach the script to has a collider attached to it. Clicking on the collider will trigger the OnMouseDown() function.
I'm creating a game where objects are being created. These objects are moving left and the player has to press space bar before the object reaches the end of the screen. Every thing works fine with the exception of spawning a prefab on the moving objects.
The idea is to spawn a animation on the nearest target. But when instantiated, the prefab always instantiate at the prefab location (0,0,0). How do I make the instantiated prefab spawn at the correct place? (I've tested with print(nearestTarget.transform.position) and the print always gives me a different location depending on the "nearestTarget")
Trying to spawn the prefab in HandSlapAnimation() Method.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerInput : MonoBehaviour
{
// Reference to levelManager
[SerializeField] LevelManager levelManager;
// Array of all present entities
private GameObject[] targets;
// Nearest entity
private GameObject nearestTarget;
// Array of all x position of all present entities
private float[] locationOfTargets;
// Nearest x position (transform.position.x) in all entities
private float nearestLocation;
// Finds the index location of the float value
private int index;
// Hand prefab to be instantiate during Keypress
public GameObject handPrefab;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
targets = GameObject.FindGameObjectsWithTag("Entities");
if (targets.Length > 0)
{
FindLocationOfEntities();
AssignNearestTarget();
HandSlapAnimation();
DestroyNearestTarget();
}
}
}
void FindLocationOfEntities()
{
locationOfTargets = new float[targets.Length];
for (int i = 0; i < targets.Length; i++)
{
locationOfTargets[i] = targets[i].transform.position.x;
}
}
void AssignNearestTarget()
{
nearestLocation = Mathf.Min(locationOfTargets);
index = System.Array.IndexOf(locationOfTargets, nearestLocation);
nearestTarget = targets[index];
}
void DestroyNearestTarget()
{
if (nearestTarget.GetComponent<CubeMovement>().isCat == true)
{
levelManager.LoadLevel("Game Over");
}
else
{
Destroy(nearestTarget);
}
}
void HandSlapAnimation()
{
// Instantiate prefab Hand GameObject at the nearest target to execute the Hand Slap animation
Instantiate(handPrefab, transform.position, Quaternion.identity);
handPrefab.transform.SetParent(nearestTarget.transform);
print(nearestTarget.transform.position);
}
}
The problem is that in:
Instantiate(handPrefab, transform.position, Quaternion.identity);
The transform.positionis the position of the actual object, your PlayerInput instance.
Then, you do: handPrefab.transform.SetParent(nearestTarget.transform) but that doesn't move the position, only sets the parent.
Instead of using transform.position in the Instantiate method, use nearestTarget.transform.position.
Instantiate(handPrefab, nearestTarget.transform.position, Quaternion.identity);
I'm trying to animate / transform a gameObject movingObject from it's spawn position to the destination. I believe the issue is somewhere in the implementation of the IncrementPosition function.
Rather than moving the one cube from A to B. The script spawns multiple cubes until it gets to B. Can you see where I'm going wrong?
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class onClickSpawnMove : MonoBehaviour
{
public float speed;
public GameObject randomSpawn;
private GameObject movingObject;
private Vector3 destination;
void Start()
{
Spawn();
}
void Update()
{
SetDestination(movingObject.transform.position);
if (destination != movingObject.transform.position) {
IncrementPosition();
}
}
void IncrementPosition()
{
float delta = speed * Time.deltaTime;
Vector3 currentPosition = movingObject.transform.position;
Vector3 nextPosition = Vector3.MoveTowards(currentPosition, destination, delta);
movingObject.transform.position = nextPosition;
}
void Spawn() {
Vector3 spawnPosition = new Vector3(10, 0, 0);
movingObject = Instantiate(randomSpawn, spawnPosition, Quaternion.identity);
}
public void SetDestination(Vector3 value)
{
destination = new Vector3(20, 0, 0);
}
}
There are several ways to call the Spawn / Start method casually:
gameObject.AddComponent<onClickSpawnMove>(); the Start method will be invoked again.
Instantiate a prefab that onClickSpawnMove script is attached already.
gameObject.SendMessage("Start"); maybe, but rarely seen.
You can add a log or break point to check when the Spawn / Start method is called.
Print the hash code will help you know the different onClickSpawnMove instances.
And you can click the message in the console to know which GameObject is.
void Start()
{
Spawn();
Debug.Log("Start " + this.GetHashCode(), this);
}
I have a very annoying bug, and I can't get rid of it.
The situation is, that I have a parent with the following script attached, and a trigger box2d collider. It has a child, with a rigidbody2d(kinematic, gravity=0, freeze position x, and rotation z), a sprite renderer and a polygon collider (with 4 edges).
My problem is, when the scene is loaded, sometimes my child objects (always random how much of them and which ones), jumps to transform.position 0,0,0.
I link the script, that is attached to the parent
using UnityEngine;
using System.Collections;
public class FallingSpikeHazard : MonoBehaviour
{
public GameObject spike;
private Rigidbody2D spikeRigidbody;
[SerializeField]
private Vector3 startPosition;
void Awake ()
{
startPosition = spike.transform.localPosition;
}
void Start ()
{
spikeRigidbody = spike.GetComponent<Rigidbody2D> ();
Helper.JustReset += ResetMe;
Invoke ("CheckPosition", Time.deltaTime);
}
void CheckPosition ()
{
if (spike.transform.localPosition != startPosition) {
Debug.LogError ("t1" + spike.transform.localPosition);
spike.transform.localPosition = startPosition;
Debug.LogError ("t2" + spike.transform.localPosition);
}
}
void OnDestroy ()
{
Helper.JustReset -= ResetMe;
}
void ResetMe ()
{
spikeRigidbody.gravityScale = 0;
spikeRigidbody.isKinematic = true;
if (startPosition != Vector3.zero) {
spike.transform.localPosition = startPosition;
}
}
void OnTriggerEnter2D (Collider2D other)
{
if (other.gameObject.tag.Equals ("Player")) {
spikeRigidbody.isKinematic = false;
spikeRigidbody.gravityScale = 1;
}
}
}
Events are not called, in other hand, if I disable the script, it keeps happening. Nothing have reference to these GameObjects. I don't have animations, or animator attached.
What could cause my problem?
You need to have a Rigidbody2D component in the parent GameObject in order for the OnTriggerEnter function to be called.