0
\$\begingroup\$

I'm a beginner in Unity and i'm facing a little problem / question. The main purpose of my 2D game is based on the mouvment of a specific light and the player have to avoid getting inside his rays. My actual game got different type of layers :

  1. Z = -5 : A front light (don't pay attention of this one)
  2. Z = 0 : The main scene, where the player move and interact with collider (2D based, player is a sprite with rigidbody2d and circlecollider2d
  3. Z = 1 : Some elements to avoid the light to go through and give the player a chance to hide
  4. Z = 10 : The main light that the player have to avoid

My problem is the following one, i don't know how to interact a Point Light (so a 3d object) and a sprite (2D). I tried to do some "OnTriggerEnter / Stay" in the Point Light but it never trigger. I heard about "Raycast" but i prefer to ask some solution before learning this. If anyone can give me tips, it would be very good :)

Thanks !

[EDIT SOLUTION, THANKS TO Géry Arduino]

#pragma strict

public var moon : Component;

function Start () {

}

function Update () {
var radiusMoon = moon.transform.light.range;
var zMoon = moon.transform.position.z;
var zPlayer = transform.position.z;
if(zMoon - radiusMoon <= zPlayer) {
    var zDirection = transform.position.z - zMoon;
    var xDirection = transform.position.x - moon.transform.position.x;
    var yDirection = transform.position.y - moon.transform.position.y;
    var direction = Vector3(xDirection, yDirection, zDirection);
    Debug.DrawRay(moon.transform.position, direction, Color.red, 10);
    if(Physics.Raycast(moon.transform.position, direction, radiusMoon)) {
        Debug.Log("there is something between me and the object....");
    } 
    else {
        Debug.Log("i'm free");
    }
}   
}
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Actually Lights does not contain colliders, but what you can do is add a CircleCollider2D component to a light, then track if your object collide with the collider of this light and only then trace a ray from your object (character) to the light, if the ray hits a collider before hitting the light then you know your character is in the shadow part of this light!

I am not sure you could go away with this without using raycast2D, but dont be afraid once you get a hold on it it can be very straight-forward.

For example to put on your character :

private bool inTheShadow = false;

void Update() {
    if(!inTheShadow) {
        //Replace following lines with your own magic
        Debug.Log("Too much Light!!");
    }
    else { Debug.Log("Vampire Secure Area!!"); }
}

void OnCollisionStay2D(Collision2D coll) {

    if (coll.gameObject.tag == "Light") {//is that component a light? (need to have the light tag on your light
        float distance = Vector3.distance(transform.position,coll.gameObject.transform.position);
        Vector3 rayDirection = (coll.gameObject.transform.position-transform.position).normalized;
        RaycastHit2D hit = Physics2D.Raycast(transform.position,rayDirection,distance);
        if(hit.collider!=coll) { //Am i hitting the light or smthing else?
            inTheShadow = true;
        }
        else {inTheShadow = false;}
    }  
}

This is a non optimized version done quickly without unity or anything related near hand

\$\endgroup\$
3
  • \$\begingroup\$ I was actually going to write a little edit on my post and ask if it was a good solution... but you did it for me :) I just have a little question, i think that one raycast is maybe not enough, maybe i should use 2 or 3 raycast depending on the type of collider no ? \$\endgroup\$
    – Kamigaku
    Mar 16, 2014 at 10:12
  • \$\begingroup\$ Well if you want to check precisely when the sprite enter or exits a light zone the you'll need 2/3 raycasts one at each extremites of your bounding box. But that would be only to add precision because empirically you can get all the data you want from only one raycast, if it hits something else before reaching the light then you know for sure that you have something between the light and the Character, if you want to filter what is hit by the raycast (transparent surfaces should be ignored for example) then you should use layers : docs.unity3d.com/Documentation/Components/Layers.html \$\endgroup\$ Mar 16, 2014 at 12:13
  • \$\begingroup\$ Done, worked very well. Just gonna put my code in the first post :) \$\endgroup\$
    – Kamigaku
    Mar 16, 2014 at 19:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .