[Unity][Javascript] Why are these simple js scripts not working in Unity? - unity3d

I've been sort of teaching myself and sort of learning from Jimmy Vegas on youtube: https://www.youtube.com/channel/UCRMXHQ2rJ9_0CHS7mhL7erg
If you haven't seen those tutorials or don't want to look, one of the things he does is create a small script that destroys a coin when the player collider hits it, but mine isn't working. Code below (a little mis-formatted, sorry, couldn't get it to format correctly):
function OnCollisionEnter (collision : Collision) {
if(collision.gameObject.tag == "coinCollect") {
Destroy(this.gameObject);
}
}
I applied the script to a prefab and placed a bunch of coins around a little area, additionally, I made a capsule collider in a first person controller tagged "coinCollect", and ticked "Is Trigger"
Also, I'm trying to make a teleporter that teleports the first person character from one teleporter to another. Code below:
var warptarget001 : GameObject;
var warptarget002 : GameObject;
function OnTriggerEnter (col : Collider) {
if (col.gameObject.tag == "warp001") {
this.transform.position = warptarget002.position;
} else if (col.gameObject.tag == "warp002") {
this.transform.position = warptarget001.position;
}
}
I have four objects here, two warp pads and two warp targets. The two warp pads are tagged "warp001" and "warp002", respectively and the two warp targets are not assigned anything in the code, but assigned by dragging and dropping an empty object into the Serialized Field the script provides. Both pads have capsule colliders with "Is Trigger" unticked but it doesn't work either way, ticked or unticked.
Can anyone tell me what I might be doing wrong? Thank you.

The script was all correct, my problem was that my parent "FPSController" object didn't have a Rigidbody applied to it and should be the only object (as opposed to the "FirstPersonCharacter" object I had nested inside of it) that the scripts are applied to. That seemed to fix the problem.
The correct code is:
/* coincollect.cs */
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class coincollect : MonoBehaviour {
private int _score;
[SerializeField]
private Text _text;
void OnTriggerEnter ( Collider collision ){
if(collision.gameObject.tag == "coin"){
Destroy(collision.gameObject);
_score++;
_text.text = "Score: " + _score;
}
}
}
and:
/* warp.js */
var warptarget001 : GameObject;
var warptarget002 : GameObject;
function OnTriggerEnter (col : Collider) {
if (col.gameObject.tag == "warp001") {
this.transform.position = warptarget002.transform.position;
}
if (col.gameObject.tag == "warp002") {
this.transform.position = warptarget001.transform.position;
}
}

The only thing I can think of for your first problem is that it shouldn't need IsTrigger ticked. Other than that, it sounds like it should work (unless I'm missing something).
For the second problem you're having (with the warps), I don't think you can use warptarget001 by dragging and dropping objects into the fields. The reason being that what you've dragged into that field isn't the same object instance that's inworld.
You should assign their values through the code (preferably in the Start method), by using GameObject.Find("name") for example. This way, warptarget001 corresponds to the inworld gameobject.

Related

how do i make sword work with enemy collider

here is my current code:
public GameObject enemy;
void OnCollisionEnter(UnityEngine.Collision collisionInfo)
{
if (collisionInfo.collider.tag == "sword")
{
Debug.Log("works");
enemy.SetActive(false);
}
else
{
Debug.Log("doesnt work");
}
}
i have attached this to the enemy and also i tried a different script attached to the sword
void OnTriggerStay(Collider col)
{
if (Input.GetButtonDown("Fire1"))
{
if (col.GetComponent<Collider>().tag == "enemy")
{
Destroy(col.gameObject);
}
}
}
both codes don't work, it seems that the problem isnt with the sword collision cus i have also added the tag to another gameobject and it doesnt work. i looked online but havent found anything that works so fat
update: it seems that i have forgot you need a rigid body for collision detection. simple mistake but it made my code not work!
For collision enter to work, both the sword and the enemy colliders need to have the "IsTrigger" box unticked.
For on triggerstay is the opposite, both need to have that box ticked.
Basically, Triggers do not collide they call that OnTriggerEnter function, while non-triggers use the OnCollisionEnter.

Why the component automatically was removed on collision event of the Unity?

My English skill is poor I'm not a native English speaker.
Please understand.
I want to make the logic that detecting collision
For that, I make a character class. The Character class inherits the MonoBehaviour of the Unity system and has a feature as below.
The class has the container to put the skill was collided with own.
The class has the coroutine to show the status of the container. This coroutine starts when the Character class starts.
The class overrides OnTriggerEnter2D function of the Unity system. In this function, the skill that collides with own is added to the container.
I made the above feature as below code.
public class Character : MonoBehaviour
{
private ConcurrentDictionary<Skill, float> _skills = new ConcurrentDictionary<Skill, float>();
protected virtual void Start()
{
StartCoroutine(Check());
}
private IEnumerator Check()
{
float delayTime = 0.1f;
First:
yield return new WaitForSeconds(delayTime);
foreach (var skill in _skills.Keys.ToList())
{
Debug.Log($"_skills: {skill}");
}
goto First;
}
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.gameObject.tag != "cold_wind") return;
var skill = collision.GetComponent<Skill>();
_skills.TryAdd(skill, 100);
}
}
And I added BoxCollider2D component to the prefab that to add the above Character class.
After then I made the Skill class. I omit the Skill class because the Skill class doesn't have a feature yet. I added BoxCollider2D and RigidBody2D components to the prefab that to add the Skill class.
Finally I checked the Simulated function of the RigidBody2D to receive a collision event.
The program executes as the below sequence.
The skill is generated for 3 seconds and it collides with the character.
OnTriggerEnter2D function of the Character was called and skill that collided was added to the container. (Concurrent<Skill, float>)
The Check coroutine shows the skill be included in the container.
Here, I have the problem. Logically I think the Skill class included in the container must not be removed automatically.
But after 3 seconds (the skill effect appears for 3 seconds) if the skill effect disappears then the Skill class included in the container was removed. At the result Check coroutine shows null as below.
Could someone tell me what I did wrong?
Any advice would be much appreciated.
Thanks for reading.
Most likely everything you are doing is working as intended. The one mistake would be unexpected behavior with TryAdd, where the value added can be null.
Inside of your OnTriggerEnter2D function, add a check to determine what you collided with to only check for spells. The easiest way to do this is check the tag of the object. For all of your spells, add a tag that you can check against, then change your collision code to look something like
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.gameObject.tag == "SpellTagHere")
{
// the issue is this line can result in NULL if another object collides with your player
var skill = collision.GetComponent<Skill>();
// meaning a null is added here
_skills.TryAdd(skill, 100);
}
}

Collision system not working. There are no errors, it just wont register that the projectile hit the player

Here is the code in which I was talking about. I can't figure out why my collider isn't working:
using System.Collections.Generic;
using UnityEngine;
public class SphereCollider : MonoBehaviour
{
GameObject obj;
void Awake ()
{
obj = GameObject.FindGameObjectWithTag("Player");
}
// Update is called once per frame
void Update()
{
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.name == "Player")
{
obj.GetComponent<Health>().health -= 25;
}
}
}
}
Rather than using the code you have, make sure to change some code. This is what you should change: get rid of the obj variable and the awake function. Then instead of finding the object with that name, use tag. Also get rid of Update(){} and take the OnCollisionEnter(){} out of it.
A few more changes are shown in code:
void OnCollisionEnter(Collision collision){
var obj = collision.GameObject;
if (obj.Tag == “Player”){
obj.GetComponent<Health>().health -= 25;
}
}
This will work as long as: the script is called Health, the variable inside Health is called health, and it is set to a float, and the player’s tag is set to Player.
Not sure if the code pasted in the question is just copied over wrong, but OnCollisionEnter() is its own unique method and should not be nested in Update().
If the player will be colliding with this Sphere object often, it is good to cache a component rather than using GetComponent frequently. However I assume in your case this Sphere will be one of many obstacles, so calling the GetComponent in the collision is fine. The issue with your current code is the gameObject you are colliding with might not have the name exactly spelled as Player, which would make your collision check fail. Caching the object that has the tag of Player is a bit redundant when you can just check it inside of the collision check.
I will use your entire snippet of code so there is no confusion
using System.Collections.Generic;
using UnityEngine;
public class SphereCollider : MonoBehaviour
{
void OnCollisionEnter(Collision col)
{
// compare if the collider's gameObjects tag is equal to our target tag (Player)
if (col.gameObject.tag == "Player")
{
// get the component of Health on our gameObject that we collided with that has the tag of Player
obj.GetComponent<Health>().health -= 25;
}
}
}

Children collider not getting called

Context
I'm working in a pickup system in my game. I've a component called AbstractSightCollider that has a sphere collider and some AbstractPickupableObject that are the objects meant to be picked up.
AbstractSightCollider is attached to the main character, but could be attached to any alive entity or anything that is able to contain inventory objects.
The way i designed it, it's that when AbstractSightCollider detects an object, it fires an UnityEvent called PickupDetected and when the player leaves the range of pickup, it call an UnityEvent called PickupLeave
The problem
I can't make OnCollisionEnter and OnCollisionExit trigger.
Some code
This is attached to AbstractSightCollider
public class AbstractObjectSight : MonoBehaviour
{
public OnPickupableDetected pickupDetected;
public OnPickupableLeave pickupLeave;
private void OnCollisionEnter(Collision col) {
GameObject gameObject = col.gameObject;
AbstractPickupableObject abstractPickupableObject =
gameObject.transform.GetComponent<AbstractPickupableObject>();
if (abstractPickupableObject != null) {
pickupDetected.Invoke(abstractPickupableObject);
}
}
private void OnCollisionExit(Collision col) {
GameObject gameObject = col.gameObject;
AbstractPickupableObject abstractInventoryObject =
gameObject.transform.GetComponent<AbstractPickupableObject>();
if (abstractInventoryObject != null) {
pickupLeave.Invoke(abstractInventoryObject);
}
}
[System.Serializable]
public class OnPickupableDetected : UnityEvent<AbstractPickupableObject> { }
[System.Serializable]
public class OnPickupableLeave : UnityEvent<AbstractPickupableObject> { }
}
And here are the properties:
Thanks for your time
Make sure both objects (the one with the script and the one that will cause the trigger) have colliders and rigidbodys, I find if one doesn't have those the triggers and collisions will not work.
I just found out the problem.
OnCollisionEnter and OnCollisionExit aren't the events that i needed to listen, because they work with rigidbody. My AbstractSight is that, a non body abstract sphere where the entities are allowed to grab items.
Instead, i used OnTriggerEnter, OnTriggerExit and now it works like a charm.
Rigid body on the parent object means the collider will work on ANY child component but the rigid body MUST be on the parent object.
Example:
MyProjectile has a rigid body and a collider - set isTrigger = true
MyEnemy parent object just holds scripts
MyEnemy childObject holds the enemy prefab including its collider,
Everything is set to isKinematic = true, with no gravity.
Everything works fine.

Detect if third person camera touches cube unity3d

What I want is to destroy the cube when the third person camera touches it...but anything i have tried so far fails...
Here is the code i have tried:
#pragma strict
var other : GameObject;
function Start () {
}
function Update () {
}
function OnCollisionEnter ( collision : Collision) {
if (collision.tag == "Character")
Destroy (collision.gameObject);
}
Thanks for any suggestions!
There are two simple ways to do this. One of them is attaching a script to the character to destroy specified objects and the other one is to attach a script to the object to be destroyed on inpact with the character, but on both of those ways you NEED the Rigidbody component to be attached too.
Adding this to the object to be destroyed and tagging the character:
[RequireComponent (typeof (Rigidbody))]
void OnCollisionEnter(Collision col)
{
if(col.gameObject.tag == "Character")
Destroy(this.gameObject);
}
OR
Adding this to the character and tagging the objects to be destroyed:
[RequireComponent (typeof (Rigidbody))]
void OnCollisionEnter(Collision col)
{
if(col.gameObject.tag == "ToBeDestroyed")
Destroy(col.gameObject);
}
remember: this code is in C#, you`ll need to convert to javascript if you are going to add to an existing script