using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using Whilefun.FPEKit;
public class RoboSphereWindowBreakInteraction : MonoBehaviour
{
public Transform target;
public InteractableObjects interactableObjects;
public AudioClip audioClip;
public float speed;
private bool hasStarted = false;
private Animator anim;
void Update()
{
if ((Input.GetKeyDown(KeyCode.B) || (hasStarted == true)))
{
float step = speed * Time.deltaTime; // calculate distance to move
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
hasStarted = true;
}
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.name == "Square 1")
{
GetComponent<Rigidbody>().isKinematic = false;
hasStarted = false;
Destroy(GameObject.Find("Wall_Window_Long_03"));
}
}
public void ActivateRoboSphere()
{
foreach(Transform child in transform)
{
if(child.name == "Camera")
{
RepositionCamera(child);
}
}
anim = GetComponent<Animator>();
anim.enabled = true;
if (!anim.GetBool("Open_Anim"))
{
anim.SetBool("Open_Anim", true);
StartCoroutine(PlayAudio());
}
else
{
//anim.SetBool("Open_Anim", false);
}
}
private void RepositionCamera(Transform camera)
{
var Eyes = GameObject.Find("eyeDome");
camera.position = Eyes.transform.position + Eyes.transform.forward;
camera.LookAt(Eyes.transform);
camera.GetComponent<Camera>().enabled = true;
}
IEnumerator PlayAudio()
{
AudioSource audio = GetComponent<AudioSource>();
audio.Play();
yield return new WaitForSeconds(audio.clip.length);
audio.clip = audioClip;
audio.Play();
}
}
It's getting inside the PlayAudio but the sound is not heard.
The audio source component screenshot settings :
The only problem I see with this code is that initially, your audio source's clip isn't set to anything. Thus will result in a null ref exception on this line:
yield return new WaitForSeconds(audio.clip.length);
Add a null check and you should be good to go
if (audioSource.clip != null)
{
yield return new WaitForSeconds(audioSource.clip.length);
}
Related
The script have two states NoEntry and NoExit.
The first problem is the TextToShow.
When the player entered/exited a collider it was showing in the text the same text.
So i changed the textToShow variable to be array type :
public string[] textToShow;
Then according to the state NoEntry/NoExit i used the TextToShow[0] and TextToShow1 and in the inspector i added a text to each textToShow :
What i want to do is to create for each collider for example the player entered or exited a collider, could be i have 10 colliders in the game for that case so if the player hit a collider to identify the collider and add to it some properties in the inspector.
or maybe another way but the idea is to create a TextArea for each collider so i can enter a text and to see in the inspector to what collider or when the text will show.
Same concept for example to the variable : targetToRotateTowards
Now when the player exit/enter he will walk backwards and rotate facing the object in the variable targetToRotateTowards instead i want that in each collider that the player will do something else for example if the collider the state is NoExit move backward face some object but if a collider state is NoEntry so the player should move backwards facing 180 degrees back and not a specific object.
And in the general to extend the script to be more generic for more situations.
Maybe using enum with many cases ? For example if the player enter the small collider he will crash falling dead but if he exit the big collider the player will go backward rotating facing an object.
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityStandardAssets.Characters.ThirdPerson;
public class DistanceCheck : MonoBehaviour
{
public Transform targetToRotateTowards;
public float lerpDuration;
public float rotationSpeed;
[TextArea(1, 2)]
public string[] textToShow;
public GameObject descriptionTextImage;
public TextMeshProUGUI text;
public ThirdPersonUserControl thirdPersonUserControl;
private Animator anim;
private float timeElapsed = 0;
private float startValue = 1;
private float endValue = 0;
private float valueToLerp = 0;
private bool startRotating = false;
private bool slowOnBack = true;
private bool exited = false;
private Vector3 exitPosition;
private float distance;
public string[] TextToShow { get => textToShow; set => textToShow = value; }
void Start()
{
anim = transform.GetComponent<Animator>();
}
private void FixedUpdate()
{
if (startRotating)
{
transform.rotation = Quaternion.RotateTowards(transform.rotation,
Quaternion.LookRotation(targetToRotateTowards.position - transform.position),
rotationSpeed * Time.deltaTime);
}
if (exitPosition != new Vector3(0, 0, 0) && slowOnBack)
{
distance = Vector3.Distance(transform.position, exitPosition);
}
if (distance > 5 && slowOnBack)
{
slowOnBack = false;
StartCoroutine(SlowDown());
}
}
private void OnTriggerExit(Collider other)
{
if (other.tag == "NoExit")
{
descriptionTextImage.SetActive(true);
text.text = TextToShow[0];
RepositionPlayer();
}
else if (other.tag == "NoEntry")
{
OnPlayerRepositioned();
}
}
private void OnTriggerEnter(Collider other)
{
if (other.tag == "NoExit")
{
OnPlayerRepositioned();
}
else if (other.tag == "NoEntry")
{
descriptionTextImage.SetActive(true);
text.text = TextToShow[1];
RepositionPlayer();
}
}
private void RepositionPlayer()
{
// Stuff that needs to happen to reposition the player
exited = true;
slowOnBack = true;
exitPosition = transform.position;
thirdPersonUserControl.enabled = false;
StartCoroutine(SlowDown());
}
private void OnPlayerRepositioned()
{
// stuff you need to do to clear the "repositioning" status
exited = false;
startRotating = false;
text.text = "";
descriptionTextImage.SetActive(false);
}
IEnumerator SlowDown()
{
timeElapsed = 0;
while (timeElapsed < lerpDuration)
{
valueToLerp = Mathf.Lerp(startValue, endValue, timeElapsed / lerpDuration);
anim.SetFloat("Forward", valueToLerp);
timeElapsed += Time.deltaTime;
yield return null;
}
if (exited)
{
yield return new WaitForSeconds(3f);
startRotating = true;
StartCoroutine(SpeedUp());
}
if (slowOnBack == false)
{
thirdPersonUserControl.enabled = true;
}
}
IEnumerator SpeedUp()
{
timeElapsed = 0;
while (timeElapsed < lerpDuration)
{
valueToLerp = Mathf.Lerp(endValue, startValue, timeElapsed / lerpDuration);
anim.SetFloat("Forward", valueToLerp);
timeElapsed += Time.deltaTime;
yield return null;
}
}
}
After creating the ColliderInfo class i added to the class two properties the second one is :
public Transform rotateTowards;
The class :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ColliderInfo : MonoBehaviour
{
[TextArea] public string onEnterText, onExitText;
public Transform rotateTowards;
}
Then in the DistanceCheck script i removed deleted the variable targetToRotateTowards and added a private ColliderInfo variable :
private ColliderInfo colliderInfo;
Then created instance in the Start :
void Start()
{
anim = transform.GetComponent<Animator>();
colliderInfo = new ColliderInfo();
}
And using it in the FixedUpdate :
private void FixedUpdate()
{
if (startRotating)
{
transform.rotation = Quaternion.RotateTowards(transform.rotation,
Quaternion.LookRotation(colliderInfo.rotateTowards.position - transform.position),
rotationSpeed * Time.deltaTime);
}
The problem is that rotateTowrads is type Transform but if i want the transform to rotate by degrees and not facing the rotateTowards transform ?
The complete DistanceCheck script after changes :
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityStandardAssets.Characters.ThirdPerson;
public class DistanceCheck : MonoBehaviour
{
public float lerpDuration;
public float rotationSpeed;
public GameObject descriptionTextImage;
public TextMeshProUGUI text;
public ThirdPersonUserControl thirdPersonUserControl;
private Animator anim;
private float timeElapsed = 0;
private float startValue = 1;
private float endValue = 0;
private float valueToLerp = 0;
private bool startRotating = false;
private bool slowOnBack = true;
private bool exited = false;
private Vector3 exitPosition;
private float distance;
private ColliderInfo colliderInfo;
void Start()
{
anim = transform.GetComponent<Animator>();
colliderInfo = new ColliderInfo();
}
private void FixedUpdate()
{
if (startRotating)
{
transform.rotation = Quaternion.RotateTowards(transform.rotation,
Quaternion.LookRotation(colliderInfo.rotateTowards.position - transform.position),
rotationSpeed * Time.deltaTime);
}
if (exitPosition != new Vector3(0, 0, 0) && slowOnBack)
{
distance = Vector3.Distance(transform.position, exitPosition);
}
if (distance > 5 && slowOnBack)
{
slowOnBack = false;
StartCoroutine(SlowDown());
}
}
private void OnTriggerExit(Collider other)
{
if (other.tag == "NoExit")
{
descriptionTextImage.SetActive(true);
if (other.TryGetComponent(out ColliderInfo info))
{
text.text = info.onExitText;
}
RepositionPlayer();
}
else if (other.tag == "NoEntry")
{
OnPlayerRepositioned();
}
}
private void OnTriggerEnter(Collider other)
{
if (other.tag == "NoExit")
{
OnPlayerRepositioned();
}
else if (other.tag == "NoEntry")
{
descriptionTextImage.SetActive(true);
if (other.TryGetComponent(out ColliderInfo info))
{
text.text = info.onEnterText;
}
RepositionPlayer();
}
}
private void RepositionPlayer()
{
// Stuff that needs to happen to reposition the player
exited = true;
slowOnBack = true;
exitPosition = transform.position;
thirdPersonUserControl.enabled = false;
StartCoroutine(SlowDown());
}
private void OnPlayerRepositioned()
{
// stuff you need to do to clear the "repositioning" status
exited = false;
startRotating = false;
text.text = "";
descriptionTextImage.SetActive(false);
}
IEnumerator SlowDown()
{
timeElapsed = 0;
while (timeElapsed < lerpDuration)
{
valueToLerp = Mathf.Lerp(startValue, endValue, timeElapsed / lerpDuration);
anim.SetFloat("Forward", valueToLerp);
timeElapsed += Time.deltaTime;
yield return null;
}
if (exited)
{
yield return new WaitForSeconds(3f);
startRotating = true;
StartCoroutine(SpeedUp());
}
if (slowOnBack == false)
{
thirdPersonUserControl.enabled = true;
}
}
IEnumerator SpeedUp()
{
timeElapsed = 0;
while (timeElapsed < lerpDuration)
{
valueToLerp = Mathf.Lerp(endValue, startValue, timeElapsed / lerpDuration);
anim.SetFloat("Forward", valueToLerp);
timeElapsed += Time.deltaTime;
yield return null;
}
}
}
Although there are other ways to solve this problem, centralized methods such as giving all the information to the player script by expanding the project also make it more difficult to control. The best way I can suggest you is to give the colliders information themselves, so create a ColliderInfo script like the one below and place it on the target areas.
public class ColliderInfo : MonoBehaviour
{
[TextArea] public string onEnterText, onExitText;
}
Once this is done, it is enough to call the information of each collider by going to that area, just as easily and with the same efficiency! The following code is written in the player and solves the problem. Keep in mind to create similar colliders just prefab them.
private void OnTriggerEnter(Collider other)
{
if (other.TryGetComponent(out ColliderInfo info))
{
Debug.Log(info.onEnterText);
}
}
private void OnTriggerExit(Collider other)
{
if (other.TryGetComponent(out ColliderInfo info))
{
Debug.Log(info.onExitText);
}
}
Extent of methods
The attribution method is not limited to text, for example you can define an enum of a general collider type to allow the player to react differently to different locations, or even to define the temperature in general.
public enum Type
{
None,
Hot,
Cold,
}
public Type type = Type.Hot;
Below is an example of such a structure that instead of defining a name and tag, how can you define everything related to properties, consider never entering player rotation codes in collider info, below from an object-oriented programming perspective this property belongs To the player.
if (other.TryGetComponent(out ColliderInfo info))
{
Debug.Log(info.onEnterText);
switch (info.type)
{
case ColliderInfo.Type.Hot:
Reposition();
inHotArea = true; // deal damage until staying in hot area
MeshRenderer.material.color = Color.red;
break;
case ColliderInfo.Type.Cold:
inColdArea = true; // slow effect like decreasing movement speed
MeshRenderer.material.color = Color.cyan;
break;
}
}
I have another issue with my animator in 2D.
Currently i have only few slopes in game, but it annoys me, because i don't know how to make animation work properly on them. This is one example:
As you can see, there is little slope. Now how my Animator looks like:
The code now looks like it:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using System;
public class PlayerMovementScript : MonoBehaviour
{
[SerializeField] float runSpeed;
[SerializeField] float jumpSpeed;
[SerializeField] float climbSpeed;
Vector2 moveInput;
Rigidbody2D playerRigidbody;
Animator playerAnimator;
CapsuleCollider2D playerCapsuleCollider;
float gravityScaleAtStart;
void Start()
{
playerRigidbody = GetComponent<Rigidbody2D>();
playerAnimator = GetComponent<Animator>();
playerCapsuleCollider = GetComponent<CapsuleCollider2D>();
gravityScaleAtStart = playerRigidbody.gravityScale;
}
void Update()
{
Run();
FlipSprite();
ClimbLadder();
Falling();
}
void OnMove(InputValue value)
{
moveInput = value.Get<Vector2>();
Debug.Log(moveInput);
}
void OnJump(InputValue value)
{
if (!playerCapsuleCollider.IsTouchingLayers(LayerMask.GetMask("Ground"))) { return; }
if (value.isPressed)
{
playerRigidbody.velocity += new Vector2(0f, jumpSpeed);
}
}
void Run()
{
Vector2 runVelocity = new Vector2(moveInput.x * runSpeed, playerRigidbody.velocity.y);
playerRigidbody.velocity = runVelocity;
bool playerHasHorizontalSpeed = Math.Abs(playerRigidbody.velocity.x) > Mathf.Epsilon;
if (playerCapsuleCollider.IsTouchingLayers(LayerMask.GetMask("Ground")))
{
playerAnimator.SetBool("isRunning", playerHasHorizontalSpeed);
} else
{
playerAnimator.SetBool("isRunning", false);
}
}
void FlipSprite()
{
bool playerHasHorizontalSpeed = Math.Abs(playerRigidbody.velocity.x) > Mathf.Epsilon;
if (playerHasHorizontalSpeed)
{
transform.localScale = new Vector2(Mathf.Sign(playerRigidbody.velocity.x), 1f);
}
}
void ClimbLadder()
{
if (!playerCapsuleCollider.IsTouchingLayers(LayerMask.GetMask("Climb"))) {
playerRigidbody.gravityScale = gravityScaleAtStart;
playerAnimator.SetBool("isClimbing", false);
playerAnimator.SetBool("isClimbingIdle", false);
return;
}
Vector2 climbVelocity = new Vector2(playerRigidbody.velocity.x, moveInput.y * climbSpeed);
playerRigidbody.velocity = climbVelocity;
playerRigidbody.gravityScale = 0;
bool playerHasVerticalSpeed = Math.Abs(playerRigidbody.velocity.y) > Mathf.Epsilon;
playerAnimator.SetBool("isClimbing", playerHasVerticalSpeed);
playerAnimator.SetBool("isClimbingIdle", !playerHasVerticalSpeed);
}
void Falling()
{
if (
playerCapsuleCollider.IsTouchingLayers(LayerMask.GetMask("Climb"))
|| playerCapsuleCollider.IsTouchingLayers(LayerMask.GetMask("Ground"))
) {
playerAnimator.SetBool("isJumping", false);
playerAnimator.SetBool("isLanding", false);
return;
}
bool playerHasVerticalSpeed = Math.Abs(playerRigidbody.velocity.y) > Mathf.Epsilon;
if (playerRigidbody.velocity.y >= 0)
{
playerAnimator.SetBool("isJumping", playerHasVerticalSpeed);
playerAnimator.SetBool("isLanding", false);
} else
{
playerAnimator.SetBool("isJumping", false);
playerAnimator.SetBool("isLanding", playerHasVerticalSpeed);
}
}
}
If my player went on slope, Animator shows my animations switch quickly between Run, Jump and Land. How to fix it to save correct jump animation?
I have a Unity project that I started a couple of days ago. It is a simple 2D top down shooting game, which is aimed to be played on smartphone platforms.
I have a Shooting script, which basically has a method called Shoot1, which spawns in a bullet.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shooting : MonoBehaviour
{
public Transform firePoint;
public GameObject BulletRedPrefab;
public GameObject BulletGreenPrefab;
public float bulletForce = 20f;
// Update is called once per frame
void Start()
{
}
void Update()
{
}
public IEnumerator Shoot1()
{
yield return new WaitForSeconds(0.00001f);
GameObject bullet = Instantiate(BulletRedPrefab, firePoint.position, firePoint.rotation);
Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
rb.AddForce(firePoint.up * bulletForce, ForceMode2D.Impulse);
}
}
I also have the Swipe script which determines the direction of the swipe, etc.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Swipe : MonoBehaviour
{
private bool tap, swipeUp, swipeDown, swipeLeft, swipeRight;
private bool isDraging = false;
private Vector2 startTouch, swipeDelta;
// Update is called once per frame
private void Update()
{
tap = swipeUp = swipeDown = swipeLeft = swipeRight = false;
if (Input.touches.Length > 0)
{
if (Input.touches[0].phase == TouchPhase.Began)
{
isDraging = true;
tap = true;
startTouch = Input.touches[0].position;
}
else if (Input.touches[0].phase == TouchPhase.Ended || Input.touches[0].phase == TouchPhase.Canceled)
{
isDraging = false;
Reset();
}
}
if (Input.GetMouseButtonDown(0))
{
tap = true;
isDraging = true;
startTouch = Input.mousePosition;
}
else if (Input.GetMouseButtonUp(0))
{
isDraging = false;
Reset();
}
swipeDelta = Vector2.zero;
if (isDraging)
{
if (Input.touches.Length > 0)
swipeDelta = Input.touches[0].position - startTouch;
else if (Input.GetMouseButton(0))
swipeDelta = (Vector2)Input.mousePosition - startTouch;
}
if (swipeDelta.magnitude > 125)
{
float x = swipeDelta.x;
float y = swipeDelta.y;
if (Mathf.Abs(x) > Mathf.Abs(y))
{
if (x < 0)
swipeLeft = true;
else
swipeRight = true;
}
else
{
if (y < 0)
swipeDown = true;
else
swipeUp = true;
}
Reset();
}
}
private void Reset()
{
startTouch = swipeDelta = Vector2.zero;
isDraging = false;
}
public Vector2 SwipeDelta { get { return swipeDelta; } }
public bool SwipeUp { get { return swipeUp; } }
public bool SwipeDown { get { return swipeDown; } }
public bool SwipeLeft { get { return swipeLeft; } }
public bool SwipeRight { get { return swipeRight; } }
}
And I have the GestureDetector script which is aimed to shoot a bullet whenever the user swipes left, right, up or down. When I tried to make the player object (which is called robot) move via swiping, it worked. But when I try calling a method from another class with swiping, it's not working.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GestrueDetector : MonoBehaviour
{
public Shooting other;
public Swipe swipeControls;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
private void Update()
{
if (GameObject.Find("robot") != null)
{
if (swipeControls.SwipeLeft)
desirePosition += Vector3.left;
other.Shoot1();
if (swipeControls.SwipeRight)
desirePosition += Vector3.right;
other.Shoot1();
if (swipeControls.SwipeUp)
desirePosition += Vector3.up;
other.Shoot1();
if (swipeControls.SwipeDown)
desirePosition += Vector3.down;
other.Shoot1();
}
}
}
I just started using unity this week, so I'm quite new to the software. Thank you very much!
For coroutines you need to call this methods like this:
StartCoroutine(Shoot1());
I a little bit changed your classes:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shooting : MonoBehaviour
{
public Transform firePoint;
public GameObject BulletRedPrefab;
public GameObject BulletGreenPrefab;
public float bulletForce = 20f;
void Start ()
{
}
void Update()
{
}
public void Shoot()
{
StartCoroutine(Shoot1());
}
private IEnumerator Shoot1()
{
yield return new WaitForSeconds(0.00001f);
GameObject bullet = Instantiate(BulletRedPrefab, firePoint.position, firePoint.rotation);
Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
rb.AddForce(firePoint.up * bulletForce, ForceMode2D.Impulse);
}
}
And for GestrueDetector:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GestrueDetector : MonoBehaviour
{
public Shooting other;
public Swipe swipeControls;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
private void Update()
{
if (GameObject.Find("robot") != null)
{
if (swipeControls.SwipeLeft)
desirePosition += Vector3.left;
other.Shoot();
if (swipeControls.SwipeRight)
desirePosition += Vector3.right;
other.Shoot();
if (swipeControls.SwipeUp)
desirePosition += Vector3.up;
other.Shoot();
if (swipeControls.SwipeDown)
desirePosition += Vector3.down;
other.Shoot();
}
}
}
Just read more about how coroutines are working in Unity - https://docs.unity3d.com/ScriptReference/Coroutine.html
I'm creating a FPS game and I have the following issue:
Sometimes, when I shoot at the enemies the hit is not recognized, even if the player is shooting in front of them. However, when they attack the player, the hit is recognized normally.
They have a box collider and a rigidbody attached to them.
This script is attached to the player:
using System.Collections.Generic;
using UnityEngine;
public class DisparaArma : MonoBehaviour
{
private GerenciaArma gerenciaArma;
public float nDisparo = 15f;
private float TempoProximoDisparo;
public float damage = 20f;
private Animator ZoomCameraIn;
private bool zoomed;
private Camera Maincamera;
private GameObject mira;
// Start is called before the first frame update
void Start()
{
gerenciaArma = GetComponent<GerenciaArma>();
ZoomCameraIn = transform.Find(Tags.LOOK_ROOT).transform.Find(Tags.ZOOM_CAMERA).GetComponent<Animator>();
mira = GameObject.FindWithTag(Tags.MIRA);
Maincamera = Camera.main;
}
// Update is called once per frame
void Update()
{
Atira();
ZoomInAndOut();
}
void Atira()
{
if (Input.GetMouseButtonDown(0))
{
if(gerenciaArma.SelecionaArma().tipoBala == WeaponBulletType.BULLET)
{
gerenciaArma.SelecionaArma().AnimacaoTiro();
DisparaBala();
}
}
}
void ZoomInAndOut()
{
if (gerenciaArma.SelecionaArma().mira_tipo == TipoMira.AIM)
{
if (Input.GetMouseButtonDown(1))
{
ZoomCameraIn.Play(Animacoes.ZOOM_IN_ANIM);
// gerenciaArma.SelecionaArma().Aim(true);
mira.SetActive(false);
print("VaiZoom");
}
if (Input.GetMouseButtonUp(1))//
{
ZoomCameraIn.Play(Animacoes.ZOOM_OUT_ANIM);
//gerenciaArma.SelecionaArma().Aim(false);
mira.SetActive(true);
}
}
}
void DisparaBala()
{
RaycastHit hit;
if(Physics.Raycast(Maincamera.transform.position, Maincamera.transform.forward, out hit))
{
if (hit.transform.tag == Tags.ENEMY_TAG)
{
hit.transform.GetComponent<ScriptVida>().DanoAplicado(damage);
}
}
}
}
And this one is attached to the enemies:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class ScriptVida : MonoBehaviour
{
private IndioAnimações indio_Anim;
private NavMeshAgent navAgent;
private IndioController indio_Controller;
public float vida = 100f;
public bool is_Player, is_Cannibal, is_Tiger;
private bool morto;
// Start is called before the first frame update
void Awake()
{
if (is_Tiger || is_Cannibal)
{
indio_Anim = GetComponent<IndioAnimações>();
indio_Controller = GetComponent<IndioController>();
navAgent = GetComponent<NavMeshAgent>();
}
if (is_Player)
{
}
}
public void DanoAplicado(float damage)
{
if (morto)
return;
vida -= damage;
if (is_Player)
{
}
if (is_Tiger || is_Cannibal)
{
if (indio_Controller.EnemyState == EnemyState.PATROL)
{
indio_Controller.chase_Distance = 50f;
}
}
if (vida <= 0)
{
JogadorMorre();
morto = true;
print(vida);
}
}
void JogadorMorre()
{
if (is_Cannibal)//
{
GetComponent<Animator>().enabled = false;
GetComponent<BoxCollider>().isTrigger = false;
GetComponent<Rigidbody>().AddTorque(-transform.forward * 50f);
indio_Controller.enabled = false;
navAgent.enabled = false;
indio_Anim.enabled = false;
}
if (is_Tiger)
{
GetComponent<Animator>().enabled = false;
GetComponent<BoxCollider>().isTrigger = false;
GetComponent<Rigidbody>().AddTorque(-transform.forward * 50f);
indio_Controller.enabled = false;
navAgent.enabled = false;
indio_Anim.enabled = false;
}
if (is_Player)
{
GameObject[] enemies = GameObject.FindGameObjectsWithTag(Tags.ENEMY_TAG);
for (int i = 0; i < enemies.Length; i++)
{
enemies[i].GetComponent<IndioController>().enabled = false;
}
GetComponent<Movimentação>().enabled = false;
GetComponent<DisparaArma>().enabled = false;
GetComponent<GerenciaArma>().SelecionaArma().gameObject.SetActive(false);
}
if (tag == Tags.PLAYER_TAG)
{
Invoke("RestartGame", 3f);
}
else
{
Invoke("TurnOffGameObject", 3f);
}
}
void RestartGame()
{
UnityEngine.SceneManagement.SceneManager.LoadScene("Gameplay");
}
void TurnOffGameObject()
{
gameObject.SetActive(false);
}
}
I think the problem is related to the box collider.
How could I solve this guys?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Teleport : MonoBehaviour {
public GameObject player;
public Camera mainCamera;
public Camera firstCam;
public Camera camera;
private List<GameObject> TeleportBooths;
private TeleportationsCore tc;
private void Start()
{
InstantiateObjects gos = GetComponent<InstantiateObjects>();
TeleportBooths = new List<GameObject>();
TeleportBooths = gos.PrefabsList();
firstCam.enabled = false;
mainCamera.enabled = false;
camera.enabled = true;
for (int i = 0; i < TeleportBooths.Count; i++)
{
TeleportBooths[i].AddComponent<TeleportationsCore>();
}
tc = GetComponent<TeleportationsCore>();
WorkingBooth();
}
private void WorkingBooth()
{
player.transform.position = TeleportBooths[tc.WorkingBooth()].transform.position;
camera.transform.position = new Vector3(TeleportBooths[tc.WorkingBooth()].transform.position.x - 10, TeleportBooths[tc.WorkingBooth()].transform.position.y + 10, TeleportBooths[tc.WorkingBooth()].transform.position.z);
camera.transform.LookAt(TeleportBooths[tc.WorkingBooth()].transform);
}
private void Update()
{
WorkingBooth();
}
}
I'm doing:
tc = GetComponent<TeleportationsCore>();
But tc is null.
And the script i want to access to:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TeleportationsCore : MonoBehaviour
{
public float spinSpeed = 2.0f;
private bool rotate = false;
private bool exited = false;
private int boothIndex = 0;
private void Start()
{
WorkingBooth();
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
Debug.Log("Player entered the hole");
rotate = true;
}
}
private void OnTriggerExit(Collider other)
{
if (other.gameObject.tag == "Player")
{
Debug.Log("Player exited the hole");
rotate = false;
exited = true;
}
}
void Rotate()
{
if (rotate)
{
if (spinSpeed == 350)
{
rotate = false;
exited = true;
boothIndex++;
WorkingBooth();
}
else
{
transform.Rotate(Vector3.up, spinSpeed * Time.deltaTime);
spinSpeed += 1f;
}
}
if (rotate == false && exited == true)
{
transform.Rotate(Vector3.up, spinSpeed * Time.deltaTime);
if (spinSpeed > 0.0f)
spinSpeed -= 1f;
}
}
public int WorkingBooth()
{
return boothIndex;
}
private void Update()
{
Rotate();
}
}
What i want is after i attach the script to all gameobject to get access the function WorkingBooth on TeleportationsCore.
And i don't want to attach the TeleportationsCore to the GameObject Teleport is attached on. So what other ways i have to access the WorkingBooth on TeleportationsCore ? Making the WorkingBooth public static ?
Change this:
for (int i = 0; i < TeleportBooths.Count; i++) {
TeleportBooths[i].AddComponent<TeleportationsCore>();
}
to:
TeleportationsCore[] tCores = TeleportBooths.Select(booth => booth.AddComponent<TeleportationsCore>());
Now just pick the core you want from the list.
Attach the TeleportationsCore script to empty game object. To get its reference, use this:
TeleportationsCore core = FindObjectOfType<TeleportationsCore>();
Use it for example in the Start function, as it is a bit slow.
You can find more in documentation.