Why is my enemy script not following the Player? - c#

Why is my enemy script not following the Player ?
using UnityEngine;
using System.Collections;
public class suivre : MonoBehaviour {
GameObject perso;
float persoposx;
float persoposy;
float persoposz;
// Use this for initialization
void Start () {
perso = GameObject.FindGameObjectWithTag ("Player");
InvokeRepeating ("follower", 1, 1);
}
// Update is called once per frame
void Update () {
persoposx = perso.transform.position.x;
persoposy = perso.transform.position.y;
persoposz = perso.transform.position.z;
}
void follower() {
GetComponent<Rigidbody>().AddForce(new Vector3(persoposx, persoposy, persoposz));
}
}
This script is a component on the enemy. The enemy doesn't follow the player, but still goes towards a direction - why?

You are missing one concept of direction vector.
Your code should look like that:
using UnityEngine;
using System.Collections;
public class suivre : MonoBehaviour
{
public float speed = 3f;
GameObject perso;
void Start ()
{
perso = GameObject.FindGameObjectWithTag ("Player");
InvokeRepeating ("follower", 1, 1);
}
void follower()
{
Vector3 directionToPlayer = perso.transform.position - this.transform.position;
directionToPlayer.Normalize ();
GetComponent<Rigidbody>().AddForce(directionToPlayer * speed);
}
}
Get rid of Update method. You don't need it here.
Then create direction vector from enemy to player, normalize it, and then pass this vector to AddForce and multiply it by speed you want.

Related

Player Jiggles When Running Into Object

I've been trying to fix this player collision script that I have but I can't figure out why. It's supposed to stop the player from running through walls, but when my player runs up against a wall, it jiggles around a ton like the script isn't running fast enough. (This code is from Sebastian Lagues coding tutorial series.)
The script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCollision : MonoBehaviour
{
Rigidbody myRigidbody;
public float speed = 5f;
Vector3 velocity;
// Start is called before the first frame update
void Start()
{
myRigidbody = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
Vector3 input = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
Vector3 direction = input.normalized;
velocity = direction * speed;
}
void FixedUpdate() {
myRigidbody.position += velocity * Time.deltaTime;
}
void OnTriggerEnter(Collider triggerCollider) {
print(triggerCollider.gameObject.name);
}
}
When I enabled Interpolate on the player and used MovePosition, it jiggled even more.
Try setting the rigidbody's collisionDetectionMode to Continous
I would also remove your velocity variable and set myRigidbody.velocity in FixedUpdate, like so:
void Update() {
}
void FixedUpdate() {
Vector3 input = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
Vector3 direction = input.normalized;
myRigidbody.velocity = direction * speed;
}
https://docs.unity3d.com/ScriptReference/CollisionDetectionMode.html

Instantiated Prefab not moving as expected

I'm having an issue instantiating Prefabs in Unity.
I'm working on a game where you have enemies moving towards you and you have to kill them. My original enemy game object moved towards the player with little to no problem, but the instantiations of that object wouldn't move.
To make matters more confusing, when I copied the game object and added it to the scene without instantiation, both game objects would move towards the player just fine.
Enemy script:
public class EnemieController : MonoBehaviour
{
[SerializeField]
float moveSpeed = 1;
[SerializeField]
private Rigidbody2D rb;
public Transform player;
public float health = 50;
void Start()
{
rb = GetComponent<Rigidbody2D>();
Debug.Log(player);
}
// Update is called once per frame
void Update()
{
MoveTowardsPlayer();
}
void MoveTowardsPlayer()
{
Vector3 mousepos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 direction = (player.position - transform.position).normalized;
rb.velocity = new Vector2(direction.x * moveSpeed, direction.y * (moveSpeed * 1));
}
}
Instantiation Code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//using System;
[System.Serializable]
public class GameManagement : MonoBehaviour
{
public GameObject circleEnemie;
public Transform player;
[SerializeField]
float moveSpeed = 1;
// Start is called before the first frame update
void Start()
{
//Get random position to spawn ball
Vector3 screenPosition = Camera.main.ScreenToWorldPoint(new Vector3(Random.Range(0, Screen.width), Random.Range(0, Screen.height), Camera.main.farClipPlane / 2));
GameObject enemie = Instantiate(circleEnemie, screenPosition, Quaternion.identity) as GameObject;
enemie.name = "enemiecircle";
enemie.tag = "Enemie";
}
// Update is called once per frame
void Update()
{
}
}
And if wanted, here are the enemies inspector specifications
Inspector Specifications
Sorry about the link, my reputation points are yet to reach 10 so I can't post images directly.
My guess would be that the Player referenced in your enemy prefab is a prefab itself that never moves.
You should make the prefab field itself of type EnemyController. This makes sure you only can reference a prefab here that actually has an EnemyController attached.
Then after Instantiate you can pass in the player reference of the GameManagement script like
public class GameManagement : MonoBehaviour
{
// Give this field the correct type
public EnemyController circleEnemie;
public Transform player;
[SerializeField]
float moveSpeed = 1;
// Start is called before the first frame update
void Start()
{
//Get random position to spawn ball
Vector3 screenPosition = Camera.main.ScreenToWorldPoint(new Vector3(Random.Range(0, Screen.width), Random.Range(0, Screen.height), Camera.main.farClipPlane / 2));
// Instantiate returns the same type as the given prefab
EnemyController enemy = Instantiate(circleEnemie, screenPosition, Quaternion.identity);
enemy.name = "enemiecircle";
enemy.gameObject.tag = "Enemie";
// Now pass in the player reference
enemy.player = player;
}
// NOTE: When not needed better remove Unity message methods
// It would just cause overhead
//void Update()
//{
//}
}
Sidenote: In your EnemyController in MoveTowardsPlayer what do you need this for?
Vector3 mousepos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Then whenever dealing with Rigidbody do the things in FixedUpdate otherwise it might break the physics and collision detection!
Then also don't use the Transform values but again the Rigidbody
private void FixedUpdate ()
{
MoveTowardsPlayer();
}
private void MoveTowardsPlayer ()
{
var direction = ((Vector2)(player.position - rb.position)). normalized;
rb.velocity = direction * moveSpeed;
}

Unity: Overlapping spawn Random Objects at Random Positions in C#

I am trying to develop a 2d game where my enemies will pop-up and disappear in random position without overlapping with each other. I am following this tutorial in youtube https://www.youtube.com/watch?v=iLTP4EbM1N4 but when my player touch a enemy then he is losing 2 lives instead of 1. I think it's because enemies randomly spawn in the same spawnpoint (I have 5 enemies). Do you have any suggestion how to fix that? Any help would be highly appreciated. Thanks in advance. Here is my two scripts:
SpawnItems.cs
using UnityEngine;
using System.Collections;
public class SpawnItems : MonoBehaviour
{
public Transform[] SpawnPoints;
public float spawnTime = .5f;
public GameObject[] Coins;
void Start ()
{
InvokeRepeating ("SpawnCoins", spawnTime, spawnTime);
}
void Update ()
{
}
void SpawnCoins()
{
for (int i = 0; i < Coins.Length; i++) {
int spawnIndex = Random.Range (0, SpawnPoints.Length);
//int objectIndex = Random.Range (0, Coins.Length);
Instantiate (Coins [i], SpawnPoints [spawnIndex].position, SpawnPoints [spawnIndex].rotation);
}
}
Destroy.cs
using UnityEngine;
using System.Collections;
public class DestoryScript: MonoBehaviour
{
public float destoryTime = .5f;
private float rotateSpeed = 300.0f;
void Start ()
{
Destroy (gameObject, destoryTime);
}
void Update ()
{
transform.Rotate (Vector3.forward * Time.deltaTime * rotateSpeed);
}
}
Orange ball overlaps with green ball
Your SpawnCoins() in SpawnItems.cs should be like:
void SpawnCoins()
{
Transform currentSpawnPoint = SpawnPoints[Random.Range(0, SpawnPoints.Length)].transform;
Instantiate (Coins [Random.Range(0, Coins.Length)], currentSpawnPoint.position, currentSpawnPoint.rotation);
}

Unity C# 2D Instantiate and manipulate a projectile as a child of player

I want to instantiate a projectile and be able to rotate it as a child of a parent player object.
My player has a 2DRigidbody and box collider 2D, my projectiles also have a 2DRigidbody and box collider 2D, so when I shoot them from the player they bounce the player everywhere, but when I try to instantiate them elsewhere the player either jumps to that location or they appear away from the player, so I'd like to instantiate them as a child of the player.
My code for the Player
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
// Calls Variables
public Rigidbody2D lazer;
public float speed = 1.0f;
public float hitpoints = 100;
public float lazerlevel = 1;
Transform ParentPlayer;
// Initalizes variables
void Start () {
}
// Updates once per frame
void Update () {
var move = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0);
transform.position += move * speed * Time.deltaTime;
if (Input.GetButtonUp("Fire1")) {
//Rigidbody2D instance = Instantiate(lazer, transform.position = new Vector3(0,-5,0), transform.rotation) as Rigidbody2D;
//Vector3 fwd = transform.TransformDirection(Vector3.down);
//instance.AddForce(fwd * 20 * lazerlevel);
GameObject objnewObject = (GameObject)Instantiate(lazer, new Vector3(0, 0, 0), transform.rotation);
objnewObject.transform.parent = ParentPlayer;
}
}
}
And my code for the lazer
using UnityEngine;
using System.Collections;
public class PlayerProjectileDoom : MonoBehaviour {
void ontriggerenter() {
Destroy(gameObject);
}
void Update () {
Destroy(gameObject, 2F);
}
}
You never assigned ParentPlayer in Player script. And you want to assign instantiated object as the child of Player. So the possible way to achieve this is to instantiate your object first, set it as child and then set the transformations to identity because after setting it as child its transformations will become relative to parent.
For example,
void Update () {
var move = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0);
transform.position += move * speed * Time.deltaTime;
if (Input.GetButtonUp("Fire1")) {
GameObject objnewObject = Instantiate(lazer) as GameObject;
objnewObject.transform.parent = transform;
objnewObject.transform.localRotation = Quaternion.identity;
objnewObject.transform.localPosition = Vector3.zero;
}
}
Second thing is in your PlayerProjectileDoom script. You did implement OnTriggerEnter in wrong way. You should be careful when you are implementing these messages.
Third thing is you are calling Destroy in Update method, however it will work if you put it in Start. I'd recommend use Update at least as possible and absolutely not for these kind of events.
It should be like,
using UnityEngine;
using System.Collections;
public class PlayerProjectileDoom : MonoBehaviour {
void Start(){
Destroy(gameObject, 2F);
}
// For 3D colliders
void OnTriggerEnter(Collider coll) {
Destroy(gameObject);
}
// For 2D colliders
void OnTriggerEnter2D(Collider2D coll) {
Destroy(gameObject);
}
void Update () {
}
}
So you are using 2D colliders so you should go with 2D collider message and remove the 3D one.
An extra note: OnTriggerEnter or OnTriggerEnter2D will execute only iff you set colliders as Trigger. You can see this Trigger check in Inspector by selecting that gameobject having any collider. But if it is not set to Trigger then you should use OnCollisionEnter2D(Collision2D coll)

Mouse clicks aren't recognized when I build Unity game

EDIT : Apparently when I select Windowed, the buttons work. Why is this? Why doesn't it work without that box selected?
I created a game in Unity and everything works fine in Unity itself. When I build and run the game, my buttons no longer recognize my mouse clicks. Why is this?
This is a basic pong game. I don't know why it would work in Unity and not outside of Unity if it was the code but here is the code.
Code :
paddle script:
using UnityEngine;
using System.Collections;
public class paddle : MonoBehaviour {
public float paddleSpeed = 1;
public Vector3 playerPos = new Vector3(0,0,0);
// Update is called once per frame
void Update () {
float yPos = gameObject.transform.position.y + (Input.GetAxis ("Vertical") * paddleSpeed);
playerPos = new Vector3 (-20,Mathf.Clamp(yPos, -13F,13F),0);
gameObject.transform.position = playerPos;
}
}
ball script:
using UnityEngine;
using System.Collections;
public class Ball : MonoBehaviour {
public float ballVelocity = 1500;
private Rigidbody rb;
private bool isPlay; //false by default
int randInt; //random ball directon when game begins
// Use this for initialization
void Awake () {
rb = gameObject.GetComponent<Rigidbody> ();
randInt = Random.Range (1,3);
}
// Update is called once per frame
void Update () {
if(Input.GetMouseButton(0) == true && isPlay == false){
transform.parent = null;
isPlay = true;
rb.isKinematic = false;
if(randInt == 1){
rb.AddForce(new Vector3(ballVelocity,ballVelocity,0));
}
if(randInt == 2){
rb.AddForce(new Vector3(-ballVelocity,-ballVelocity,0));
}
}
}
}
enemy script:
using UnityEngine;
using System.Collections;
public class Enemy : MonoBehaviour {
public float speed = 8;
private Vector3 targetPos;
private Vector3 playerPos;
private GameObject ballObj;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
ballObj = GameObject.FindGameObjectWithTag ("ball");
if (ballObj != null) {
targetPos = Vector3.Lerp (gameObject.transform.position, ballObj.transform.position, Time.deltaTime * speed);
playerPos = new Vector3 (-20, Mathf.Clamp (targetPos.y, -13F, 13F), 0);
gameObject.transform.position = new Vector3 (20, playerPos.y, 0);
}
}
}
score script:
using UnityEngine;
using System.Collections;
public class Score : MonoBehaviour {
public TextMesh currScore;
public GameObject ballPref;
public Transform paddleObj;
GameObject ball;
private int score;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
ball = GameObject.FindGameObjectWithTag("ball");
currScore.text = "" + score;
}
void OnTriggerEnter(Collider other) {
if(other.tag == "ball"){
score += 1;
Destroy(ball);
(Instantiate(ballPref, new Vector3(paddleObj.transform.position.x + 1, paddleObj.transform.position.y,0), Quaternion.identity) as GameObject).transform.parent = paddleObj;
}
}
}
title screen script:
#pragma strict
function Start () {
}
function Update () {
}
function StartGame () {
Application.LoadLevel("Main");
}
function ExitGame () {
Application.Quit();
}
From what I am understanding, you want Unity to recognize your mouse button event even when the mouse pointer is not inside the game Window.
There could be 2 ways to achieve this:
1. The easy way, make your game full screen.
2. If you want your game in a window box, you must check "Run In Background" option in Player settings -> Resolution. And then, learn how to hook mouse event: http://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C
Please note that the hooking mouse event tutorial only works on Windows, not Mac nor Linux. I do not know how to do it with Mac or Linux.

Categories

Resources