Magnet script issues in Unity - c#

I'm trying to make a magnet PowerUp in Unity. I used this script, which I attached to the coin GameObject:
public GameObject attractedTo;
private float strengthOfAttraction = 3f;
void FixedUpdate ()
{
Vector3 direction = attractedTo.transform.position - transform.position;
gameObject.GetComponent<Rigidbody>().AddForce (strengthOfAttraction * direction);
}
I have two problems :
1. Only newly spawn coins are attracted to the player
2. For some reason, the coins move only in straight lines, so most of them goes past the player
Anyone knows how this can be fixed?
Any help will be appreciated!

Major issue on your code. You have to recreate your procedure logic on how you make the coins get closer to the Player.
First Major problem is this.
void FixedUpdate() So on a fix amount of time per frame. You are trying to
Declare a Variable Vector3 : Vector3 direction = attractedTo.transform.position - transform.position;
So frame will recalculate and create a new pointer name direction then you try to find gameObject.GetComponent<Rigidbody>().AddForce (strengthOfAttraction * direction);
your Own Component in your gameObject. Then Call Addforce. AddForce. And you didn't even use time.deltatime.
Addforce Will push the rigidbody depending on the direction you input. So it will go straight. And you are doing this Every Fix amount of frame per sec.
First fix your procedure. My recommendation is this.
Use the Smooth Follow script. Made by Unity3D get your Reference there. It is also installed already in the script section in your Editor. If you are having problem finding it, go to this link and check he script.
Smooth Follow Script
[Update Answer]
For the 2nd Problem that only new coins is getting attracted.
Check all of this situations.
Your Player is newly spawned and your attractedTo variable is blank.
Non newly spawned coins should have referenced to the Player already, if not you have to tell all the coins that if you spawn the Player, they needed to be attracted to Player. -> Assign attractedTo when Player Spawned.
You can either Achieve that on Instantiate then find all GameObjects with TAG. Then getcomponent then assign attractedTo
Your non Spawned coins, doesn't have the Script Component.
Your non Spawned coins, is disabled.

Related

Unity: Enemy objects passing through box collider on edges of background

I'm developing a simple 2D Unity game (which I'm very new to so sorry if this is a silly question!) in which my player can eat its enemies by colliding with them. This works fine as I'm just selecting the "is trigger" component for the enemies and using this code in my Player class:
private void OnTriggerEnter2D(Collider2D other)
{
Debug.Log("Hit detected");
Destroy(other.gameObject);
transform.localScale += new Vector3(x, y, z);
}
However, this means the colliders placed around the border of my background image aren't stopping the enemies. What's the best fix for this?
I don't understand very well your question. However it seems that your collisions are not working. So, remember that for have collisions actually taking place in your game you need to use colliders and that one of the two elements participating in the collision need to have the rigidbody component.
That will make the physics work in the engine, which triggers dont.
To check if that works you can debug with:
// called on collision
void OnCollisionEnter2D(Collision2D col)
{
Debug.Log("OnCollisionEnter2D");
}
From what I understood, you want only to detect triggers between the player and the enemies, but you still want these to collide with physic objects in your scene, such as background colliders.
One possible way to achieve this is to create a child object for the player object with a collider component with the trigger option set, and attaching a script to it to handle the triggers. Then, with the use of layers to group your player and enemy objects, you can uncheck the collision between them following: Edit -> Project Settings -> Physics 2D: "Layer Collision Matrix".
You can assign a script to any enemy, checking the distance with the player in each frame. Then you can Uncheck "is trigger"
Vector2.Distance

Why does my script, which aims to remove gravity when the game starts, not work?

I'm trying to create a script in Unity wherein the gravity will go to zero when the game starts. The problem is, the gravity was still there after I launched the game.
This is for a Unity3D game. I've already tried to change the variable name, add using System; and moved my script to the top of the Rigidbody component, but none of these things worked.
public class PlayerGrav : MonoBehaviour
{
public Rigidbody rb;
void Start()
{
rb.useGravity = false;
}
void Update()
{
}
}
I expected the gravity to be removed when the game launches, but in the actual output the gravity still remained, and the cube still fell downwards.
create a new scene
create a new cube
add rb = this.GetComponent<Rigidbody>() to your start function in your PlayerGrav script
attach your PlayerGrav script to the new cube
Hit play, and take look at the "use gravity" property from your new cube's inspector window (make sure the inspector isn't locked to other game object)
If the above tryout succeeds, then you need to check the other code/objects in your original scene. If there are massive other objects in your original scene, then I will suggest disable other objects first, and re-enable them back group by group to see which object/monobhevaiour is causing the issue.
I know this is an old question but I looked forever trying to find an answer to this. I am new to unity so it took me a long time to figure this out but I am using a Rigidbody 2d so this is what worked for me
gameObject.GetComponent<Rigidbody2D>().gravityScale = 0;

How come the Collider falls from the GameObject when a RigidBody is added?

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

Attach an Animator to a clone GameObject

I am instantiating game objects by a For loop:
Dragon Manager script:
//Instantiate prefab
enemyDragons2[i] = (GameObject)Instantiate(enemyDragonStandIn,
PlaceToSpawn - Vector3.forward * 20.4f, Quaternion.identity);
//Attach script
enemyDragons2[i].AddComponent<SeekChase>();
In the SeekChase script, I have at the beginning:
static Animator anim;
and in the Start I have:
anim GetComponent<Animator>();
In the Unity editor I have everything set up: State Machine ,Parameter, Transitions and Conditions, to play from one animation, and then to another when a condition is met.
I thought that each clone game object would have the static Animator and the anim GetComponents() parts attached, but I have continuously received the error: "No Animator attached to the Clone game Object, but a script is trying to access it". This points to ,(place of the error(s):
anim.SetBool ("isIdol",false);
anim.SetBool ("isTurning",true);
I also tried to add to SeekChase:
**public**static Animator anim; (though it dosent seem like I should have to do this.)
In the Dragon Manager script( where the objects are instantiated) I tried adding the line:
static Animator anim; (in the Start)
and
anim = enemyDragons[i].AddComponent<Animator>();
I recieved the error: "animator is not playing an animator controller"
But animations don't seem to play through code, just the default take, but not transition to the next("isTurning").It seems like I am missing something simple.
Any help will be appreciated.
Thank You.
============================================
EDIT/Solution
To begin. Unity should not let you continue if there is a level error, because it gives you a false sense of being about the functioning of things.
When I was testing, I was using ONE prefab, (of 6), to test animations on. They all were using the SeekChase script. So when I would press Play, I would always get the errors:
"No Animator attached to the Clone game Object, but a script is trying to
access it".
I sort of expected an error because the other instantiated objects were having their Animators accessed by the SeekChase script, though they did not have one. Since I was testing on one object that was being instantiated, and Unity allowed me to "Play", I did not think that that error was related to the functioning of my current animation problem.
With your suggestions, I was able to, in the State Machine, with transitions arrows attached, have the two animations play from one to the other ( this wasn't being done before). But, with the condition that I had to set the bool:
if(direction.magnitude < 10.0f)
{
// Animator Stuff####
anim.SetBool("isIdol",true);
anim.SetBool("isTurning",true);...
}
..... the second animation was not being played.
Then I thought about the persistent error, and decided to comment out SeekChase script being applied to the other game objects......and then the second animation it played!
Hopefully when I fix all the prefabs and insatiate them, all will function.
Thanks again.
First make enemyDragonStandIn as gameobject without instantiating with the animations working, then make that gameobject prefab, after that you can instantiate it with the rigth animations instead of adding them on runing time. Finally call on the instantiated object
anim.SetBool ("isTurning",true)

Jump OnCollision() Script not working

basically, I'm trying to make a game that is based off automatically hopping as soon as the ground is hit(the Controller I'm using is the pre-made one that can be imported).In order to do this, I removed the jump function from the controller script and added a script called "Cube" which reads as the following:
using UnityEngine;
using System.Collections;
public class Cube : MonoBehaviour {
void OnCollisionStay (Collision col)
{
if (col.gameObject.name == "Blue") {
Rigidbody rig;
rig= GetComponent<Rigidbody> ();
rig.velocity = new Vector3 (0, 8, 0);
print ("collison detected");
}
}
}
after doing this, I expected a controllable character which jumps as soon as you hit the ground because of the "OnCollisionStay()" trigger. However, instead I get a rapid jump that happens even when I'm in the air which looks like this:
https://youtu.be/ILtRac_RgLg
First of all, undo everything modification you performed to the RigidbodyFirstPersonController script. If possible, delete it and re-import a clean one from Unity.
Select your RigidBodyFPSController GameObject, Look at the RigidbodyFirstPersonController script attached to it in the Editor. Under it there is a setting called Advanced Settings. Under Advanced Settings, there is variable called Shell Offset. Change Shell Offset from its default value of 0 to 0.5. Play again and this problem should be gone. If that didn't work, bump it up more. This should solve your problem.
You are not in the air as the gravity is effecting on it. Whenever you are exiting the collision your y-axis upward velocity is not working and gravity force is taking place downward.
Disable gravity in FPSController's Rigidbody component if you don't want to use gravity.

Categories

Resources