Transform position don't change gameObject position - c#

I want to make respawn my player to the spawn point when he has a contact with a projectile. The event onTriggerEnter is triggered when the event occurs, but the player position do not changed.
I tried to solve my problem with other.transform.position = spawnPoint; and other.gameObject.transform.localPosition = spawnPoint; or other.transform.localPosition = spawnPoint; but it does not change anything.
Here is my code :
using UnityEngine;
public class Projectil : MonoBehaviour {
private Vector3 spawnPoint;
void Start() {
spawnPoint = GameObject.Find("SpawnPoint").GetComponent<Transform>().localPosition;
}
void OnTriggerEnter(Collider other) {
if(other.CompareTag("Player")) {
other.gameObject.transform.position = spawnPoint;
Debug.Log("touched : " + other.transform.position );
}
}
}

When two objects with a physical collider collide, OnCollisionEnter is called. Only when one of them is not physical, i.e. Is Trigger is set on the collider, then OnTriggerEnter is called.
Related Unity Documentation pages:
Scripting - Collider.isTrigger
Manual - Sphere Collider

Related

Player health will not go down

i have tried to make it so whenever the enemy collides with Player1 health drops, i have all of the public floats and transforms setup, but the health in the debug menu shows it just doesnt go down, any ideas?
(attached to player1)
using System.Collections;
using System.Collections;
using UnityEngine;
public class PlayerHealth : MonoBehaviour
{
private float health = 0f;
public Transform player;
[SerializeField] private float maxHealth = 100f;
private void Start() {
health = maxHealth;
}
public void UpdateHealth (float mod) {
health += mod;
if (health > maxHealth){
health = maxHealth;
} else if (health <= 0f){
health = 0f;
Debug.Log("Player Respawn");
}
}
}
attached to enemy:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyAttack : MonoBehaviour
{
[SerializeField] private float attackDamage = 10f;
[SerializeField] private float attackSpeed = 1f;
public Transform player;
private float canAttack;
// Start is called before the first frame update
private void OnCollisionStay2D(Collision2D other) {
if (other.gameObject.tag == "Player1"){
if (attackSpeed <= canAttack){
other.gameObject.GetComponent<PlayerHealth>().UpdateHealth(-attackDamage);
canAttack = 0f;
}else {
canAttack += Time.deltaTime;
}
}
}}
You are serializing the Max Health, not the current health, so the value shown in the inspector will never change. Add the SerializeField to the health value as well and you'll see the current health.
[SerializeField]
private float health = 0f;
Beyond that, it's difficult to see if the code isn't working. I would ensure that the tag you're checking for is actually set on the Player, and add a debug message to OnCollisionStay2D to ensure the collision handler is being called. If it isn't, ensure you have the collider components on both the enemy game object and the player gameobject.
Depending on your intention, you may want to move the canAttack modifier to Update(), since your current logic will only "refresh" the canAttack timer when the enemy is actually colliding with the player. If the enemy hits a player and the player runs away, and comes back ten minutes later and runs into the enemy, the enemy won't attack, they'll only start "healing" their canAttack timer until it's ready again. Maybe this is what you want, but I suspect that it should go into Update() so enemies that have already attacked "rest up" at all times.

There is no Rigidbody 2D attached to the game object but the script is trying to access it

Here is the code I'm using. It throws a MissingComponentException: There is no Rigidbody 2D attached to "Bird" game object but the script is trying to access it.
using System.Collections;
public class Bird : MonoBehaviour
{
public float UpForce; //Upward force of the "flap".
private bool _isDead = false; //Has the player collided with a wall?
private Animator _anim; //Reference to the Animator component.
private Rigidbody2D _rb2d; //Holds a reference to the Rigidbody2D component of the bird.
void Start()
{
//Get reference to the Animator component attached to this GameObject.
_anim = GetComponent<Animator> ();
//Get and store a reference to the Rigidbody2D attached to this GameObject.
_rb2d = GetComponent<Rigidbody2D>();
}
void Update()
{
//Don't allow control if the bird has died.
if (_isDead == false)
{
//Look for input to trigger a "flap".
if (Input.GetMouseButtonDown(0))
{
//...tell the animator about it and then...
_anim.SetTrigger("Flap");
//...zero out the birds current y velocity before...
_rb2d.velocity = Vector2.zero;
// new Vector2(rb2d.velocity.x, 0);
//..giving the bird some upward force.
_rb2d.AddForce(new Vector2(0, UpForce));
}
}
}
void OnCollisionEnter2D(Collision2D other)
{
// Zero out the bird's velocity
_rb2d.velocity = Vector2.zero;
// If the bird collides with something set it to dead...
_isDead = true;
//...tell the Animator about it...
_anim.SetTrigger ("Die");
//...and tell the game control about it.
GameControl.instance.BirdDied ();
}
}
How do I provide the reference it wants?
The GameObject this script is attached to should have a RigidBidy2D component (because the script is using it to apply forces to GameObject). You can either add a Rigidbody2D in inspector (choose the GameObject the script is attached to and use "Add Component" menu), or make it so the script adds a component automatically when you attach it to GameObject by adding a RequireComponent attribute like this:
[RequireComponent(typeof(Rigidbody2D))]
public class Bird : MonoBehaviour
{
//your Bird class code here
}
See also these questions - that's the same problem.

Enemy follow player when player is not looking. OnBecameInvisible not working

So I want to create a weeping angels effect on my enemies in my game. So when the player can see the enemy, they don't move and when the player can't see them, they move closer to the player. This is my code thats attached to the enemy and its not working. Would really appreciate some help!
using System.Collections.Generic;
using UnityEngine;
public class WeepingAngel : MonoBehaviour
{
public GameObject Player;
// Start is called before the first frame update
void Start()
{
Player = GameObject.FindGameObjectWithTag("Player");
}
void OnBecameInvisible()
{
if (Player)
{
transform.position = Player.transform.position - Player.transform.forward;
Vector3 lookPos = Player.transform.position - transform.position;
lookPos.y = 0;
transform.rotation = Quaternion.LookRotation(lookPos);
}
}
}
I'm gonna assume that the OnBecameInvisible doesn't get called in situations where you think it should. The reason why that may happen is because it will react to ANY camera. That includes even the scene view.
Alternative solution
Instead of OnBecameInvisible you can use the method available in this wiki article:
http://wiki.unity3d.com/index.php?title=IsVisibleFrom
Modified version of your code
using UnityEngine;
public class WeepingAngel : MonoBehaviour
{
public GameObject player;
private new Camera camera;
private new Renderer renderer;
private void Start()
{
player = GameObject.FindGameObjectWithTag("Player");
camera = Camera.main;
renderer = GetComponent<Renderer>();
}
private void Update()
{
bool isVisible = GeometryUtility.TestPlanesAABB(
GeometryUtility.CalculateFrustumPlanes(camera),
renderer.bounds);
if (!isVisible)
TryMovingTowardsPlayer();
}
private void TryMovingTowardsPlayer()
{
if (player == null)
return;
transform.position = player.transform.position - player.transform.forward;
Vector3 lookPos = player.transform.position - transform.position;
lookPos.y = 0;
transform.rotation = Quaternion.LookRotation(lookPos);
}
}

Object is not triggering collider

Hi my problem is in Unity, I am a beginner in c#, my gameObject is not triggering the collider that is set on the plane of the game, in order for it to reset it's position.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BasketballSpawnScript : MonoBehaviour
{
public Transform respawnPoint;
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Basketball"))
{
other.gameObject.transform.position = respawnPoint.position;
}
}
}
This script is attached to the plane and the gameobject is tagged with Basketball, when it enters the collider of the floor it should transform it's position to the original position.
I cannot see what is wrong, can I receive some help?
P.S I get this error when other gameobject go through the collider too.
NullReferenceException: Object reference not set to an instance of an object
If using a Transform for spawn point, remember to set the value of it in the inspector menu.
public Transform respawnPoint;
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Basketball"))
other.transform.position = respawnPoint.position;
}
else
public Vector3 respawnPoint = Vector3.zero;
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Basketball"))
other.transform.position = respawnPoint;
}
private void OnTriggerEnter(Collider other){
if(other.gameobject.tag=="Basketball"){
other.gameobject.transform.position = respawnPoint;
}
}
I hope it helps you.

How do I stop AI movement with OnTriggerEnter2D in Unity?

I'm creating a basic AI script for my enemies in Unity and I have most of it working the way I want it to. The way I have my enemies set up they contain 2 colliders, a polygon collider that destroys the player when touched, and an empty game object that's a child of the enemy that is a circle collider that acts as a trigger. There's a game object that's tagged Straight Road and when the circle collider comes in contact with it, it should run a function called StopMovement(); that sets the enemies movement to 0. I used to Debug.Log(); to check to see if the collider recognizes that it's touching Straight Road and it doesn't. This is my code below. I'm hoping someone has a suggestion.
public class DogAI : GenericController {
public Transform target;
public float chaseRange;
public float maxDistance;
private Vector3 targetDirection;
private float targetDistance;
// Use this for initialization
void Start()
{
base.Start();
}
// Update is called once per frame
void Update()
{
base.Update();
if (target.transform != null)
{
targetDirection = target.transform.position - transform.position;
targetDirection = targetDirection.normalized;
targetDistance = Vector3.Distance(target.position, transform.position);
if (targetDistance <= chaseRange)
{
SetMovement(targetDirection);
}
Vector3 enemyScreenPosition = Camera.main.WorldToScreenPoint(transform.position);
if (targetDistance > maxDistance)
{
Destroy(gameObject);
}
}
}
void StopMovement()
{
SetMovement(new Vector2(0,0));
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Straight Road"))
{
Debug.Log("Stop! There's a road!");//This never shows up in the log?
StopMovement();
}
}
void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.CompareTag("Player"))
{
DestroyObject(other.gameObject);
}
}
Generic Controller script below containing the SetMovement() function.
public abstract class GenericController : MonoBehaviour
{
public float movementSpeed = 20;
float animationSpeed = 1;
protected Rigidbody2D rigidbody;
protected Animator animator;
Vector2 movementVector;
float currentSpeed;
protected bool needAnimator = true;
// Use this for initialization
protected void Start()
{
rigidbody = GetComponent<Rigidbody2D>();
if (needAnimator)
{
animator = GetComponent<Animator>();
animator.speed = animationSpeed;
}
}
protected void FixedUpdate()
{
rigidbody.velocity = movementVector;
currentSpeed = rigidbody.velocity.magnitude;
if (needAnimator)
animator.SetFloat("Speed", currentSpeed);
}
public void SetMovement(Vector2 input)
{
movementVector = input * movementSpeed;
}
public void SetMovement(int x, int y)
{
SetMovement(new Vector2(x, y));
}
From the documentation:
MonoBehaviour.OnTriggerEnter2D(Collider2D)
Sent when another object enters a trigger collider attached to this object (2D physics only).
The keyword here is enters. In other words, a trigger is for when something goes inside the area of the collider, like a player entering a region of the map, where the region is a trigger collider. If you want something to happen when a collider collides with the road, i.e. when your CircleCollider comes in contact with the road, then you want the collider to not be a trigger, and you want the functionality to be inside OnCollisionEnter2D.

Categories