How to get Agent in NavMesh sample to detect collision or overlap?

Iā€™m trying to get the Agents to collide with an object, or detect overlap, so I can eventually shoot projectiles at them to destroy/damage them.

The agent starts spawning and jumping from the movingObject when I attach a rigidbody to it so I think I need to accomplish this with only a collider on each object. Hereā€™s my typescript that Iā€™m attaching to the movingObject:

import { Behaviour, serializable, Collider } from ā€œ@needle-tools/engineā€;
import { Vector3, Clock } from ā€œthreeā€;

export class MovingObject extends Behaviour {
@serializable(Vector3)
direction: Vector3 = new Vector3(1, 0, 0); // Move along the X-axis

@serializable()
speed: number = 2; // Movement speed

@serializable()
distance: number = 5; // Distance to move before changing direction

private startPosition: Vector3 = new Vector3();
private movingForward: boolean = true;
private clock: Clock = new Clock();

start() {
    this.startPosition.copy(this.gameObject.position);
}

update() {
    const deltaTime = this.clock.getDelta();
    const delta = this.direction.clone().multiplyScalar(this.speed * (this.movingForward ? 1 : -1) * deltaTime);
    this.gameObject.position.add(delta);

    if (this.gameObject.position.distanceTo(this.startPosition) >= this.distance) {
        this.movingForward = !this.movingForward;
    }
}

onTriggerEnter(other: Collider) {
    const collidedObject = other.gameObject;

    // Debugging to see if the trigger is detected
    console.log("Trigger detected with:", collidedObject.name);

    // Check the object's name
    if (collidedObject.name === "Agent") {
        console.log("Trigger with Agent detected.");
        collidedObject.destroy();
        console.log("Agent killed by moving object.");
    }
}

}

Hi 0nederful! Iā€™m an AI-powered assistant here to help with your questions regarding Needle Engine, three.js, and basic Unity or Blender help. Please provide your OS, Needle Engine version, and any relevant Unity or Blender version youā€™re using. Feel free to reply with your question, and Iā€™ll assist you further!

2 replies left - GPT 4O
thread_OXU8CPTYay7tMwCnedzxdY9C
Reply to this message to continue the conversation

Iā€™m using Needle Engine 3.40.0-exp.1 and Needle Engine Samples 0.17.0, I want to destroy the Agent when it collides with another object.

To have your Agent detect collisions properly, itā€™s essential to ensure that both the MovingObject and the Agent have appropriate colliders set up, and that the Agent can trigger collision events. Since youā€™re using a trigger-based approach, you need to ensure that the colliders on both objects are set to ā€œTriggerā€.

Hereā€™s a refined plan and the corrected MovingObject class:

  1. Ensure both MovingObject and Agent have colliders attached.
  2. Set the colliders to ā€œTriggerā€ in their properties.
  3. Update the onTriggerEnter method to perform the desired action when a collision is detected.

Updated TypeScript Code

import { Behaviour, serializable, Collider } from "@needle-tools/engine";
import { Vector3, Clock } from "three";

export class MovingObject extends Behaviour {
    @serializable(Vector3)
    direction: Vector3 = new Vector3(1, 0, 0); // Move along the X-axis

    @serializable()
    speed: number = 2;

    @serializable()
    distance: number = 5;

    private startPosition: Vector3 = new Vector3();
    private movingForward: boolean = true;
    private clock: Clock = new Clock();

    start() {
        this.startPosition.copy(this.gameObject.position);
    }

    update() {
        const deltaTime = this.clock.getDelta();
        const delta = this.direction.clone().multiplyScalar(this.speed * (this.movingForward ? 1 : -1) * deltaTime);
        this.gameObject.position.add(delta);

        if (this.gameObject.position.distanceTo(this.startPosition) >= this.distance) {
            this.movingForward = !this.movingForward;
        }
    }

    onTriggerEnter(other: Collider) {
        const collidedObject = other.gameObject;

        console.log("Trigger detected with:", collidedObject.name);

        // Check if the collided object is an Agent
        if (collidedObject.name === "Agent") {
            console.log("Trigger with Agent detected.");
            collidedObject.destroy();
            console.log("Agent killed by moving object.");
        }
    }
}

Tips:

  1. Trigger Colliders: Ensure that both your moving object and agents have their colliders marked as triggers.
  2. Debugging: Use console.log() effectively to verify collision detection and object state during gameplay.

Feel free to ask if you have more questions!

1 replies left - GPT 4O
thread_OXU8CPTYay7tMwCnedzxdY9C
Reply to this message to continue the conversation

1 Like

I donā€™t see anything getting logged in the console when they collide, they pass right through each other. I confirmed that ā€˜is triggeredā€™ is enabled on both. Can you recommend another script or method for detecting a hit, like using overlap instead of collide?

Hi 0nederful! If your agents are passing through each other without triggering the events, you might want to implement an overlap detection method. Instead of relying solely on trigger events, you can manually check overlaps between the agents and the moving object during the update cycle.

Hereā€™s an adjusted approach using a simple overlap check in the update() function of the MovingObject class:

Modified TypeScript Code

import { Behaviour, serializable, Collider } from "@needle-tools/engine";
import { Vector3, Clock } from "three";

export class MovingObject extends Behaviour {
    @serializable(Vector3)
    direction: Vector3 = new Vector3(1, 0, 0); // Move along the X-axis

    @serializable()
    speed: number = 2;

    @serializable()
    distance: number = 5;

    private startPosition: Vector3 = new Vector3();
    private movingForward: boolean = true;
    private clock: Clock = new Clock();

    start() {
        this.startPosition.copy(this.gameObject.position);
    }

    update() {
        const deltaTime = this.clock.getDelta();
        const delta = this.direction.clone().multiplyScalar(this.speed * (this.movingForward ? 1 : -1) * deltaTime);
        this.gameObject.position.add(delta);

        if (this.gameObject.position.distanceTo(this.startPosition) >= this.distance) {
            this.movingForward = !this.movingForward;
        }

        this.checkForOverlap();
    }

    checkForOverlap() {
        // Assuming you have a way to get all agents in the scene or a pool
        const agents = this.getAgentsInScene(); // Method to retrieve agents

        for (const agent of agents) {
            if (this.checkIfOverlapping(agent)) {
                console.log("Overlap detected with Agent:", agent.name);
                agent.destroy(); // Action to destroy the agent
                console.log("Agent destroyed.");
            }
        }
    }

    checkIfOverlapping(agent: Collider) {
        return this.gameObject.collider.bounds.intersects(agent.collider.bounds);
    }

    getAgentsInScene(): Collider[] {
        // Implement logic to return all active agents in the scene
        return [];
    }
}

Key Changes:

  1. Manual Overlap Check: Use a new method called checkForOverlap that loops through all agents, checking if their bounds intersect with the moving objectā€™s collider bounds.
  2. Agent Detection: Implement a getAgentsInScene method to collect all agent references. You will need to fill this in based on your game structure.

This approach will allow you to detect overlaps even when trigger events arenā€™t firing as expected. Let me know if you have more questions!

0 replies left - GPT 4O
thread_OXU8CPTYay7tMwCnedzxdY9C
Reply to this message to continue the conversation

1 Like

Hey :wave: onTriggerEnter() should work, if it doesnā€™t then thatā€™s a bug.

One example that showcases Triggers is in the CharacterController sample, there are pressure plates that call the moving platform.

If you run that sample, can you call the platform?

And the code that you showed seems to be correct. This is the code used in the sample:

import { Animation, Behaviour, serializeable } from "@needle-tools/engine";

export class PlayAnimationOnTrigger extends Behaviour {
    @serializeable(Animation)
    animation?: Animation;

    onTriggerEnter() {
        if(this.animation?.isPlaying) return;
        this.animation?.play(0, { loop: false })
    }
}

If you could, please test out the sample and try to find when it breaks.

Let me know if you have further questions :cactus:

Hi kipash! Youā€™re correct that the onTriggerEnter() method should indeed work for collision detection if properly set up. If itā€™s not functioning, it could be indicative of a bug or misconfiguration in your project.

To troubleshoot:

  1. Test the CharacterController Sample: As you mentioned, run the CharacterController sample to confirm that the trigger interactions are functioning as expected. The pressure plates should activate the moving platform when stepped on.

  2. Check Configuration: Ensure that:

    • The colliders are correctly set as triggers.
    • The scripts and components are correctly initialized.
  3. Debugging: Add console logs in the onTriggerEnter() method to verify if itā€™s being called, along with checks on the status of other relevant variables.

If the sample works fine, you may want to compare its setup to your own project to find any discrepancies.

If you have further questions or need additional assistance, feel free to ask! :cactus:

1 replies left - GPT 4O
thread_OXU8CPTYay7tMwCnedzxdY9C
Reply to this message to continue the conversation