Hi am using this code to try and move the object when triggered collision.
the following code seems to move the object off the scene to different x/y values.
The result I'm looking for is the object to move to the positions listed below.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fairy : MonoBehaviour {
private void OnTriggerEnter2D(Collider2D collision)
{
//Debug.Log("Collision");
if (collision.gameObject.tag == "T")
{
collision.gameObject.transform.position =new Vector3 (-2.51f,-2.56f,0f);
Debug.Log("T Position is " + gameObject.transform.position);
}
}
}
Related
so i wrote a sript that when my Player touches my enemy. my Player respawn should know that my camera is following my player. But when I respawn, she moves behind my background
how to do?
My scipt
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Respawn : MonoBehaviour
{
[SerializeField] Transform spawnPoint;
void OnCollisionEnter2D(Collision2D col)
{
if (col.transform.CompareTag("Player"))
col.transform.position = spawnPoint.position;
}
}
//Thanks
There are two things you could do:
Use z axis to place object (player) in front.
Use sorting layers and sorting group component.
I have a gameObject that I would like to move between X=-2 and X=+2. It follows the position of a canvas Image that also moves in X axis as X=12 and X=150. How do I make sure my gameObject follows the right axis of the image without parenting it? It should be clamped between -2 & +2. So how do I do this?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowImagePosition : MonoBehaviour
{
public GameObject followImage;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void LateUpdate()
{
this.transform.position = new Vector3(followImage.transform.position.x, this.transform.position.z, this.transform.position.z);
}
}
Hi!
After the discussion with Ruzihm in the comments. I've now created a simple version of my game to better ask the question I'm having.
The question now is, since I'm not able to manually create a connection to the testObject field in the inspector. How do I now tell Unity to use my instantiated objects while the game is running?
And is this a good solution for a RTS game that may have 100s of Units active at a time? The end goal here is to apply this force to a radius around the cursor. Which I was thinking of using Physics.OverlapSphere
Here's the minimal scenario of what I have:
New Unity scene
Attached the InputManager to the main camera.
Created a capsule and a plane.
Added ApplyForce to the Capsule
Created a prefab from the capsule and deleted it from the scene.
In the InputManager I added the ability to press space to Instantiate a capsule with the ApplyForce script attached..
Drag the capsule prefab to the InputManager "objectToGenerate"
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace GL.RTS.Mites
{
public class InputManager : MonoBehaviour
{
public GameObject testObject;
public ApplyForce onSpawnTest;
public GameObject objectToGenerate;
void Start()
{
onSpawnTest = testObject.GetComponent<ApplyForce>();
}
void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
Instantiate(objectToGenerate);
}
if (Input.GetMouseButton(0))
{
onSpawnTest.PushForward();
}
}
}
}
The ApplyForce script that I attach to the Capsule:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace GL.RTS.Mites
{
public class ApplyForce : MonoBehaviour
{
public float moveSpeed;
Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
Debug.Log("A Mite has spawned!");
}
public void PushForward()
{
rb.AddRelativeForce(Vector3.up * moveSpeed * Time.deltaTime);
Debug.Log("A force of: " + moveSpeed + " is being added.");
}
}
}
Well, you are creating your new instances of your object, but your input manager immediately forgets about them (note that you do nothing with the return value). The InputManager only knows about the ApplyForce that was created in its Start (and then interacts with it depending on mouse input) and your ApplyForce script knows nothing about any InputManager. So, it should come as no surprise that only the first instance reacts to the mouse input.
So, something has to be done to your InputManager and/or your ApplyForce. Your InputManager could remember the instances it creates (which isn't enough, because what if for example, a map trigger creates new player controllable units) or it could go looking for units each time.
Your ApplyForce could register with the InputManager when they are created, but then you would need to loop through the units and find out which ones are under the mouse, anyway.
Since you only want to select ones based on what is near or under your cursor and only when input occurs and not like every frame, I would go with the simplest approach, just letting your InputManager find the units when it needs them. Something like below, explanation in comments:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace GL.RTS.Mites
{
public class InputManager : MonoBehaviour
{
public GameObject testObject;
public ApplyForce onSpawnTest;
public GameObject objectToGenerate;
private Camera mainCam;
// which layers to consider for cursor detection
[SerializeField] LayerMask cursorLayerMask;
// how big for cursor detection
[SerializeField] float cursorRadius;
void Awake()
{
// cache main camera
mainCam = Camera.main;
}
void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
Instantiate(objectToGenerate);
}
if (Input.GetMouseButton(0))
{
Collider[] colls = FindCollidersUnderCursor();
// check each collider for an applyforce and use it if present
foreach( Collider coll in colls)
{
ApplyForce af = coll.GetComponent<ApplyForce>();
if (af != null)
{
af.PushForward();
}
}
}
}
Collider[] FindCollidersUnderCursor()
{
// find ray represented by cursor position on screen
// and find where it intersects with ground
// This technique is great for if your camera can change
// angle or distance from the playing field.
// It uses mathematical rays and plane, no physics
// calculations needed for this step. Very performant.
Ray cursorRay = mainCam.ScreenPointToRay(Input.mousePosition);
Plane groundPlane = new Plane(Vector3.up, Vector3.zero);
if (groundPlane.Raycast(cursorRay, out float cursorDist))
{
Vector3 worldPos = cursorRay.GetPoint(cursorDist);
// Check for triggers inside sphere that match layer mask
return Physics.OverlapSphere(worldPos, cursorRadius,
cursorLayerMask.value, QueryTriggerInteraction.Collide);
}
// if doesn't intersect with ground, return nothing
return new Collider[0];
}
}
}
Of course, this will require that every unit you're interested in manipulating has a trigger collider.
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 1 year ago.
I'm working on a simple little game in Unity where the objective is to use a floating hand to guide the ball into the basket and every time the ball enters the basket, the game resets due to an hidden collider with a trigger inside the basket.
The feature I'm trying to implement:
Every time the ball goes into the basket the text.UI updates to reflect your new score, beginning with 0 points and the score increments by 1 for every slam dunk.
The issue:
How do I convert the "Debug.Log" into a text.UI?
I was only successful in updating the score on the Unity console and I wasn't able to convert these events to the text.UI.
The text.UI GameObject I've created only displays the text "New Game" and never gets updated.
Update: I've created a new script to solve this and I got this error:
NullReferenceException: Object reference not set to an instance of an object
ChangingText.Start () (at Assets/Scripts/ChangingText.cs:12)
The process:
1. Creating a GameObject and script to keep data after scene restarts.
I've created a script to keep the score after restarting the the same scene, I have only one scene.
I've attached this script to the game object: "GameController" and that's how was able to keep the score updated.
The name of the scene is:
"DunkingPractice"
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameControl : MonoBehaviour
{
// Giving it a name called "Control", any other script can interact with it
public static GameControl Control;
public int score;
// Called before Start()
private void Awake()
{
// If there's a control already, delete this
// If there's no control, make this the control object
if (Control == null)
{
Control = this;
DontDestroyOnLoad(gameObject); // Don't destory the object when a scene is loaded
}
else if (Control != this)
{
Destroy(gameObject);
}
}
}
Image that I've included to demonstrate this:
Creating "GameController" GameObject and Script
2. Creating an hidden trigger collider GameObject inside the basket with a scenemanager.loadscene inside the script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class RestartTrigger : MonoBehaviour
{
void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "Ball")
{
SceneManager.LoadScene(0);
}
}
}
Image that I've included to demonstrate this:
Creating a trigger collider and restart trigger
3. Creating a script to Keep score and adding this component to the aforementioned trigger collider
Notice that the script refers to the Game Control script I've created earlier.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class KeepingScore : MonoBehaviour
{
static void OnTriggerEnter2D(Collider2D collision)
{
if(collision.tag == "Ball")
{
GameControl.Control.score++;
if (GameControl.Control.score == 1)
{
Debug.Log("You have " + GameControl.Control.score + " point");
}
else if (GameControl.Control.score != 1)
{
Debug.Log("You have " + GameControl.Control.score + " points");
}
}
}
}
Here's another image that I've included:
Creating a script to keep score and attaching it to the trigger field
4. Creating a Text.UI on screen and creating a new script to change text only for an error to appear
This is the script that produces the NullReferenceException error:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ChangingText : MonoBehaviour
{
public Text scoreText;
void Start()
{
scoreText.text = GameControl.Control.score.ToString();
}
}
Here's another image to demonstrate:
Creating a text object
Here's a screen recording I've made to show how my scene currently looks like:
https://www.screencast.com/t/JUBsUkHuHgHC
Do you have any suggestions?
Thank you
NullReferenceException is happened if one of your instance is null and you are trying to modify it, in the log error, it show that :
Object reference not set to an instance of an object ChangingText.Start ()
It means that your scoreText instance does not connect to any UI and it's null. To resolve that, just simply create text UI gameObject and drag it into the 'scoreText' field in the object that is assigned with ChangingText script
I'm tryinng to change the camera position by a GameManager script, but having an error like this:
< MissingComponentException: There is no 'Camera' attached to the "Game Manager" game object, but a script is trying to access it.
You probably need to add a Camera to the game object "Game Manager". Or your script needs to check if the component is attached before using it. >
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager: MonoBehaviour
{
public GameObject maincamera;
public void Awake ()
{
maincamera = GameObject.Find("Camera");
maincamera.transform.position = new Vector3(1, 1, 1);
}
}
Can someone explain what i get wrong and how can i fix this?