[SOLVED] How to modify Enemy AI script

this s an updated version where it is activated by a certain key being pressed the script activates.
Script:

var Enemy = pc.createScript('enemy');

Enemy.attributes.add('enemyCamera', {type: 'entity', title: 'Camera Entity'});
Enemy.attributes.add('enemyTarget', {type: 'entity', title: 'Target Entity'});
Enemy.attributes.add('enemyGround', {type: 'entity', title: 'Ground Entity'});
Enemy.attributes.add('enemySpeed', {type: 'number', default: 0.1, title: 'Enemy Speed'});

// initialize code called once per entity
Enemy.prototype.initialize = function() {
    this.enemyCanSeeTarget = false;
    this.enemyDestination = new pc.Entity();
};

// update code called every frame
Enemy.prototype.update = function(dt) {
    this.searchTarget();
    this.detectObstacle();
    this.moveEnemy(dt);
};

Enemy.prototype.moveEnemy = function (dt) {
    var destination = new pc.Vec3(this.enemyDestination.getPosition().x, 1, this.enemyDestination.getPosition().z);
    var distanceToDestination = this.entity.getPosition().distance(destination);

    // move the enemy based on the current state
    if (!this.enemyCanSeeTarget) {
        if (distanceToDestination > 0.1) {
            this.entity.lookAt(destination);
            this.entity.translateLocal(0,0, -this.enemySpeed*dt);
        }
        else {
            this.randomDestination();
        }
    }
    else {
        this.entity.lookAt(this.enemyDestination.getPosition());
        
        if (distanceToDestination > 2) {
            this.entity.translateLocal(0,0, -this.enemySpeed*dt*2);
        }
    }
};

Enemy.prototype.detectObstacle = function () {
    this.app.systems.rigidbody.raycastFirst(this.entity.getPosition(), this.enemyDestination.getPosition(), function (result) {
        
        // check if there is an obstacle in the way
        // prevent the enemy is moving inside an obstacle
        if (result.entity.name == 'Obstacle') {
            var distanceToObstacle = this.entity.getPosition().distance(result.point);
            
            if (distanceToObstacle < 2) {
                this.randomDestination();
            }
        }
    }.bind(this));
};

Enemy.prototype.searchTarget = function () {
    var target = this.enemyTarget.getPosition();
    var distanceToTarget = this.entity.getPosition().distance(target);
    
    // check if target is in range, so close enough to see
    if (distanceToTarget < 40) {
        target.sub(this.entity.getPosition()).normalize();
        var dot = target.dot(this.entity.forward);
        
        // check if target is front, so spottable or already spotted
        if (dot > 0.5 || this.enemyCanSeeTarget) {
            this.app.systems.rigidbody.raycastFirst(this.entity.getPosition(), this.enemyTarget.getPosition(), function (result) {
                
                // check if target is in view, so no obstacles in the way
                if (result.entity.name == 'Player') {
                    this.enemyCanSeeTarget = true;
                    this.enemyDestination.setPosition(this.enemyTarget.getPosition().x, 1, this.enemyTarget.getPosition().z);
                }
                else {
                    this.enemyCanSeeTarget = false;
                }
            }.bind(this));
        }
        else {
            this.enemyCanSeeTarget = false;
        }
    }
    else {
        this.enemyCanSeeTarget = false;
    }
};

Enemy.prototype.randomDestination = function () {
    var xPosition = pc.math.random(-this.enemyGround.getLocalScale().x/2, this.enemyGround.getLocalScale().x/2);
    var zPosition = pc.math.random(-this.enemyGround.getLocalScale().z/2, this.enemyGround.getLocalScale().z/2);
    this.enemyDestination.setPosition(xPosition, 1, zPosition);
};

this is the original script used
Credit: Albertos

Hi @Mason_Rocchio!

Please make sure there is a question in your topics, otherwise it can be confused for other users.

If I understand you correctly you want to make a change to the above script? Can you specify this please?

1 Like

Ok so what I want to do is activate that script when the letter m is pressed

So the script is off when the project starts and activates when the m key is pressed

I think the easiest is to change the initialize and update function like the way below.

// initialize code called once per entity
Enemy.prototype.initialize = function() {
    this.enemyCanSeeTarget = false;
    this.enemyDestination = new pc.Entity();
    this.activated = false;
};

// update code called every frame
Enemy.prototype.update = function(dt) {
    if (this.activated) {
        this.searchTarget();
        this.detectObstacle();
        this.moveEnemy(dt);
    }
    else if (this.app.keyboard.isPressed(pc.KEY_SPACE)) {
        this.activated = true;
    }
};
// initialize code called once per entity
Enemy.prototype.initialize = function() {
    this.enemyCanSeeTarget = false;
    this.enemyDestination = new pc.Entity();
    this.activated = false;
};

// update code called every frame
Enemy.prototype.update = function(dt) {
    if (this.activated) {
        this.searchTarget();
        this.detectObstacle();
        this.moveEnemy(dt);
    }
    else if (this.app.keyboard.isPressed(pc.KEY_SPACE)) {
        this.activated = true;
    }
};

Enemy.prototype.moveEnemy = function (dt) {
    var destination = new pc.Vec3(this.enemyDestination.getPosition().x, 1, this.enemyDestination.getPosition().z);
    var distanceToDestination = this.entity.getPosition().distance(destination);

    // move the enemy based on the current state
    if (!this.enemyCanSeeTarget) {
        if (distanceToDestination > 0.1) {
            this.entity.lookAt(destination);
            this.entity.translateLocal(0,0, -this.enemySpeed*dt);
        }
        else {
            this.randomDestination();
        }
    }
    else {
        this.entity.lookAt(this.enemyDestination.getPosition());
        
        if (distanceToDestination > 2) {
            this.entity.translateLocal(0,0, -this.enemySpeed*dt*2);
        }
    }
};

Enemy.prototype.detectObstacle = function () {
    this.app.systems.rigidbody.raycastFirst(this.entity.getPosition(), this.enemyDestination.getPosition(), function (result) {
        
        // check if there is an obstacle in the way
        // prevent the enemy is moving inside an obstacle
        if (result.entity.name == 'Obstacle') {
            var distanceToObstacle = this.entity.getPosition().distance(result.point);
            
            if (distanceToObstacle < 2) {
                this.randomDestination();
            }
        }
    }.bind(this));
};

Enemy.prototype.searchTarget = function () {
    var target = this.enemyTarget.getPosition();
    var distanceToTarget = this.entity.getPosition().distance(target);
    
    // check if target is in range, so close enough to see
    if (distanceToTarget < 40) {
        target.sub(this.entity.getPosition()).normalize();
        var dot = target.dot(this.entity.forward);
        
        // check if target is front, so spottable or already spotted
        if (dot > 0.5 || this.enemyCanSeeTarget) {
            this.app.systems.rigidbody.raycastFirst(this.entity.getPosition(), this.enemyTarget.getPosition(), function (result) {
                
                // check if target is in view, so no obstacles in the way
                if (result.entity.name == 'Player') {
                    this.enemyCanSeeTarget = true;
                    this.enemyDestination.setPosition(this.enemyTarget.getPosition().x, 1, this.enemyTarget.getPosition().z);
                }
                else {
                    this.enemyCanSeeTarget = false;
                }
            }.bind(this));
        }
        else {
            this.enemyCanSeeTarget = false;
        }
    }
    else {
        this.enemyCanSeeTarget = false;
    }
};

Enemy.prototype.randomDestination = function () {
    var xPosition = pc.math.random(-this.enemyGround.getLocalScale().x/2, this.enemyGround.getLocalScale().x/2);
    var zPosition = pc.math.random(-this.enemyGround.getLocalScale().z/2, this.enemyGround.getLocalScale().z/2);
    this.enemyDestination.setPosition(xPosition, 1, zPosition);
};

is this right?

Yes. Does it work for you?

Hold on
I have try it

Yeah it worked
thanks

1 Like