I have a script that makes the swamp track and follows the player. It workes fine. But when I ad an animation to the enemy (a swamp jumping towards the player) it doesn't move.
I've tried removing the position under animation, but then the swamp does not jump. It just scales. This does though fixe the problem with not following the player. so I think the problem is the animation on the position.
public class EnemyAI : MonoBehaviour
{
public float speed;
private Transform playerPos;
void Update()
{
transform.position = Vector2.MoveTowards(transform.position, playerPos.position, speed * Time.deltaTime);
}
}
Animation is the reason that takes over the position and the script becomes useless. As you have mentioned it jumps (Y-axis) and the position in the animator controller takes over. I would suggest try doing two things:
(a) Add a parent to this swamp gameObject and add animation for jumping to this parent
(b) Add MoveTowards() function to Swamp gameObject.
Through this, the parent gameObject will only perform animation of jumping and the child gameObject will perform MoveTowards() function.
Related
I'm just starting out with Unity and for my first game I'm trying to make these enemy cubes chase the player. The enemies are spawned at a random position and I'm trying to make them move towards the position of the player cube. But when I try to reference the player's Transform, it won't let me drag it on top, any fixes?
using UnityEngine;
public class enemyFollow : MonoBehaviour {
public Transform player;
public Rigidbody rb;
public float movementForce;
// Update is called once per frame
void FixedUpdate()
{
if (player.position.x > transform.position.x){
rb.AddForce(movementForce * Time.deltaTime,0,0);
}
if (player.position.x < transform.position.x){
rb.AddForce(-movementForce * Time.deltaTime,0,0);
}
if (player.position.z > transform.position.z){
rb.AddForce(0,0,movementForce * Time.deltaTime);
}
if (player.position.z < transform.position.z){
rb.AddForce(0,0,-movementForce * Time.deltaTime);
}
}
}
Unity won't let me drag the player from the gameobjects window onto the script on the prefab. The error says "the variable player of enemyFollow has not been assigned"
It won't let me assign Player.
You can add this in a void Start() method:
player = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
If I'm understanding correctly, you're trying to assign the player to the enemy in the prefab configuration. That won't work because the prefab isn't in the scene. Since the prefab could be instantiate in any scene, you can't reference scene objects. You need to do it during playtime, unless all the enemies are already in the scene when you're setting it up (in which case you'd need to do it to an instantiated enemy and then copy paste it).
You can use FindGameObjectWithTag() as in Jeff's answer, but make sure to assign a "Player" tag to the player GameObject or prefab.
Another method which I'd recommend would be to have whatever is instantiating the enemies assign their target, that way you don't need to search for a tag with a string you could mistype, and you can just change the reference in one place when you need to change something.
I'm developing an enemy AI in a 2D Game that I'm working on. This enemy swims and I wanted to make a "floating effect" animation for the enemy, so I made an animation where the Y Axis of the game object bounces up and down.
I Use transform.Translate() to move the enemies in the game and it worked just fine until I made this animation. But, when the animation is playing, the enemy can't move in any direction.
public virtual void Move(float speed)
{
if (canMove)
{
transform.Translate(new Vector2(speed, 0) * Time.deltaTime);
}
}
Once you have a keyframe in any state of your animator for a certain property the animator will always overrule any changes done in a script because the animation updates are all done after Update. You could try to either move your code to LateUpdate.
Or in your specific case you do not want the x component of your position keyframed at all. Simply remove all the keyframes for the x (and z) component(s) of the position from the animations so only y has keyframes. This should solve your problem.
Alternatively use your movement script on a GameObject on a higher level in the hierachy as your Animator - meaning add a new GameObject, make the animated object a child of it and place your movement script instead on that parant object.
I could really need some help with my GameObjects.
I am working on a game in which I want a pick-up Item to create a Physics Force explosion to blow away the enemies. I made a simple Bomb-Object to test this idea. I added a straightforward code, using a loop to collect all the colliders within its radius, to then addForce to these colliders. Now the code is working properly, but not all my GameObjects are reacting properly.
I looked into why this is, and I noticed that my Collider keeps falling away from the GameObject as soon as I add a RigidBody component to the object. The RigidBody is needed for the AddForce impact. When I remove the rb, the collider stays in place, but the object does not react to the Physics Force.
I added some images to illustrate what I mean:
Image of the Collider of the leaf sinking away..
Example image of objects which DO react to the AddForce.
I already tried to:
Copy/Paste all component settings from the reacting Cube and stone
Gameobjects to the Leaf Gameobject while disabling all other code
such as the c# scripts. The Collider & RB do not fall through the
floor but when Physics Force hits the Collider is blown away while
the GameObject keeps its position.
Try different GameObjects/Collider types.
Removed the water.
Play with amount of force/radius of the bomb.
Edited 'Tag' and 'Layerstyle' of GameObject.
The 'Explosion Code' is added below, however, I don't think the problem is in the code. I added the code to the Main Camera of my scene, and added a simple sphere as the 'bomb' GameObject.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Explosion : MonoBehaviour
{
public GameObject bomb; //set the position of the explosion
public float power = 10.0f;
public float radius = 10.0f;
public float upForce = 0.0f;
private void FixedUpdate()
{
if (Input.GetKeyDown("space"))
{
print("space key was pressed");
Invoke("Detonate", 1);
}
}
void Detonate()
{
Vector3 explosionPosition = bomb.transform.position; //set the position of our explosion to the position of the bomb.
Collider[] colliders = Physics.OverlapSphere(explosionPosition, radius); //collects all colliders within the radius.
foreach (Collider hit in colliders) { //for each individual collider the following code is ran.
Rigidbody rb = hit.GetComponent<Rigidbody>(); //declare'rb' rigidbody. Get rb component from each collider
if (rb != null)
{
print("BOOM!");
rb.AddExplosionForce(power, explosionPosition, radius, upForce, ForceMode.Impulse); //add force to each collider
}
}
}
}
How do I make the Rigidbody, Collider and GameObject of the leaf hold onto each other like the standard 3D object 'cube', so that I can make these blow away with the Physics Force just like the other models?
Thank you for your time, I have been trying things and looking around on the Internet for hours now but can't seem to find any solution.
What happens if you add the rigidbody in stop mode and press play? Does it move away in a similar manner? This may, and is expected to happen, if your colliders intersect with each other. As soon as you add a rigidbody, they find themselves trapped in a serious collision.
If you don't want to modify the scene, you can fiddle with the collision matrix in project settings / physics
I am working on a game which has strong base on spherical gravity. But somehow my code is not working as expected. So please have a look at my code and tell me how can I make my spherical gravity work.
public class CircularGravity : MonoBehaviour {
private Rigidbody2D rigid;
[SerializeField]
Transform planet;
[SerializeField]
float acceleration = 0.81f;
// Use this for initialization
void Start () {
rigid = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update () {
rigid.AddForce((planet.position - transform.position).normalized * acceleration);
transform.rotation = Quaternion.LookRotation(planet.position - transform.position, transform.up);
}
}
Problem elaboration. Project is 2d. it contains a circle sprite as a planet with a collider and hexagon has a player(just a prototype) with collider and rigidbody. This script is attached to the player(hexagon). According to my logic rigidbody should apply a force to the player and push it towards the planet and it should face the planet. So even if the player is on the downward side of circle it shouldnot fall instead it shall be pushed toward the planet. But all the colliders are being neglected and player is just going to strange position
First things I would check...
Make sure the origin of your sprite is actually in the center of the image. If it's in the corner the player will be pulled toward the corner.
Make sure both the planet and player have rigid bodies and colliders. Click on the collider and make sure the edge lines up with you shapes.
Make sure both the planet and the player have their z set to zero. Lock z in both rigidbodies.
I am testing to make a cube move with a script. Also have a simple Roll animation for the cube which is supposed to activate whenever I move the cube.
But the cube doesn't move when the animation is 'checked' as active under the inspector tab. The cube only moves if I disable animation thus not even able to see if the animation works properly when I move the cube. The cube is imported from Blender to Unity. Please advice what I am doing wrong.
The script is as follows. It is a very simple and small test file thus I have attached my Unity and Blender files too at Dropbox for reference if that helps. Thank you.
Link to Unity Project:
https://www.dropbox.com/sh/cvpjf26i31o1ell/AABmLMqYV4tPiG7qruph2D4Ra?dl=0
Link to Blender model and animation:
https://www.dropbox.com/s/deowh3yk5wpse1u/box.blend?dl=0
Movement script for cube:
public float speed = 10.0F;
Animator anim;
void Update()
{
float translation = Input.GetAxis("Vertical") * speed;
translation *= Time.deltaTime;
transform.Translate(0, 0, translation);
Animating(translation);
}
void Animating(float v)
{
bool roll = v != 0f;
anim.SetBool("Roll", roll);
}
I've updated the project and put it back up on dropbox
https://dl.dropboxusercontent.com/u/9274763/MechanimTester%20v2.zip
I added a new emtpy gameobject and made the blender cube a child of that.
The TestScript is now attached to that new gameobject and controls its position.
The animation now only applies to the child object and so the animation is no longer
interfering with the position of cube.
(What was happening was that the animation was modifying the transform for the gameobject - now as its a child its not affecting its parent so it doesn't reset the position of the overall gameobject
Does that make sense ?
Garrett