CharacterController and Normal rigidbody Box Collider Collision issues - unity3d

I am having collision issues in various different cases. I will mention each of them and will wait for your help.
Case 1:
I have an object moving with characterController attached and moving through this plugin: http://u3d.as/content/hedgehog-team/...ck-buttons/2Uo
The objects to which the characterController collides are rigidbody with box colliders attached. Most of the times the collision works perfectly with natural collision effects such as falling of crates etc and OnCollisionEnter of the objects with rigidbody and box collider is called without any problem. But sometimes, this stops. There is no collision with objects no falling and OnCollisionEnter is not called.
I try debugging and searched on google but nothing helpful Found.
Case 2:
I have an object moving with characterController attached and moving with its "SimpleMove" function.
In this case none of the collision happen, no falling, no natural effect and no calling of OnCollisionEnter on objects which have rigidbody and box collider attached.
Please help fix this errors, I have been trying to fix these since 4 days but no luck, finally I am posting here. Will wait your replies.
Thanks. Have a great day!

Does the CharacterController have a RigidBody attached with 'isKinematic' checked?

Add this script to your object :
#pragma strict
var layerMask : LayerMask; //make sure we aren't in this layer
var skinWidth : float = 0.1; //probably doesn't need to be changed
private var minimumExtent : float;
private var partialExtent : float;
private var sqrMinimumExtent : float;
private var previousPosition : Vector3;
private var myRigidbody : Rigidbody;
//initialize values
function Awake() {
myRigidbody = rigidbody;
previousPosition = myRigidbody.position;
minimumExtent = Mathf.Min(Mathf.Min(collider.bounds.extents.x, collider.bounds.extents.y), collider.bounds.extents.z);
partialExtent = minimumExtent*(1.0 - skinWidth);
sqrMinimumExtent = minimumExtent*minimumExtent;
}
function FixedUpdate() {
//have we moved more than our minimum extent?
var movementThisStep : Vector3 = myRigidbody.position - previousPosition;
var movementSqrMagnitude : float = movementThisStep.sqrMagnitude;
if (movementSqrMagnitude > sqrMinimumExtent) {
var movementMagnitude : float = Mathf.Sqrt(movementSqrMagnitude);
var hitInfo : RaycastHit;
//check for obstructions we might have missed
if (Physics.Raycast(previousPosition, movementThisStep, hitInfo, movementMagnitude, layerMask.value))
myRigidbody.position = hitInfo.point - (movementThisStep/movementMagnitude)*partialExtent;
}
previousPosition = myRigidbody.position;
}
And don't forget to specify which layer you want to detect.
Good luck !

Related

Unity2D - natural physics for two colliding spheres/balls

In my 2D Unity game, balls can bounce off each other. My goal is to have them bounce off each other as you would expect physically in the real world.
The only difference is that the speed of the balls decreases, but they can never come to a stop.
I have different approaches to map the physical behavior. But none of them leads to a good result.
(1)
private void OnCollisionEnter2D(Collision2D collision) {
var point = collision.GetContact(0);
var curDire = transform.TransformDirection(Vector2.up);
var newDir = Vector2.Reflect(curDire, point.normal);
transform.rotation = Quaternion.FromToRotation(Vector2.up, newDir);
speed *= 0.75f;
}
I don't know how describe exactly: It can happen that the balls push past each other. They collide, but do not bounce off each other, but maintain their direction.
Another approach I have read about is to add an AddForce to the velocity of Rigidbody2D.
Then the following code should do the physics.
private void Start()
{
rb = GetComponent<Rigidbody2D>();
_velocity = new Vector3(1f, 1f, 0f);
_rb.AddForce(_velocity, ForceMode2D.Force);
}
private void OnCollisionEnter2D(Collision2D collision) {
var inDirection = GetComponent<Rigidbody2D>().velocity;
var inNormal = collision.contacts[0].point;
var newVelocity = Vector2.Reflect(inDirection, inNormal);
rb.velocity = newVelocity;
}
The results are really random. I think I use a wrong AddForce or the velocity-Vector is strange. I fall here the deeper mathematical understanding to fully comprehend this solution.
(3) Then I read about Physic Material 2D. This sounds best. I created one (Asset -> Create -> 2D -> Physic Material 2D). Set bounciness to 1 the friction to 0.1. I select my Ball-prefab and add the physic material to my collider. I added it to the Rigidbody2D, too. But this asset has no effect. (My balls have no gravity. I don't know if this is important.)
I imagine Unity has a super simple solution for this problem. But I just can't find it. Does anyone have any ideas or approaches for me? I actually just want shot balls to bounce off each other. This should look as much as possible like it would look in real life.
Update Question
I move the ball like that
private Vector3 _inDirection;
private void Start()
{
_inDirection = Vector3.right * (speed * Time.deltaTime * (_didCollide ? -1 : 1));
}
private void FixedUpdate()
{
transform.Translate(_inDirection);
}

How to create a projectile Script in Unity

so recently my friends and I are trying to make a game for fun. Currently, I hit a wall and not sure how to do this. I am trying to create a simple base script where I have the character move and attack with right click. If it hits the ground, it will move there and and if in range of a target, it will send a projectile. So the game is creating the projectile but its not actually moving. Can anyone tell me what I should probably do. At first, I thought to just make it all one script but now I am thinking it be best to make another script for the projectile.
void Update()
{
if (Input.GetMouseButtonDown(1))
{
RaycastHit hit;
if(Physics.Raycast (Camera.main.ScreenPointToRay(Input.mousePosition), out hit) && hit.transform.tag == "Minion")
{
if(Vector3.Distance(this.transform.position, hit.point) <= atkRange)
{
GameObject proj = Instantiate(bullet) as GameObject;
proj.transform.position = Vector3.MoveTowards(this.transform.position, target, atkSpd);
}
}
else if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, speed))
{
agent.destination = hit.point;
}
}
}
So this is what I originally had. I am pretty sure I did something wrong here. Also I am not sure if I should have another script for the projectile itself or if it is not necessary. Thank you for any help or tips on what to do.
For starters, I'd advize using a Rigidbody component and letting physics handle movement but if you'd like to use Vector3.MoveTowards, it'll be a bit of work:
Vector3.MoveTowards is something that needs to be called every frame. I'm guessing bullet is your prefab so you'll want to make a new script for the movement and place it on that prefab:
public class MoveToTarget : MonoBehaviour
{
private float _speed;
private Vector3 _target;
public void StartMovingTowards(Vector3 target, float speed)
{
_target = target;
_speed = speed;
}
public void FixedUpdate()
{
// Speed will be 0 before StartMovingTowards is called so this will do nothing
transform.position = Vector3.MoveTowards(transform.postion, _target, _speed);
}
}
After you've attached this to your prefab, make sure you grab a reference and get it started when you instantiate a copy of your prefab:
GameObject proj = Instantiate(bullet) as GameObject;
var movement = proj.GetComponent<MoveToTarget>();
movement.StartMovingTowards(target, atkSpd);
If you instead go the physics route, add a Rigidbody component to your bullet prefab, and get a reference to that instead of making the MoveToTarget script:
GameObject proj = Instantiate(bullet) as GameObject;
var body = proj.GetComponent<Rigidbody>();
Then you can just apply a force and let physics take over:
body.AddForce(target - transform.position, ForceMode.Impulse);
Don't set the position like you currently are
proj.transform.position = Vector3.MoveTowards(this.transform.position, target, atkSpd);
Instead, add either a characterController or a rigidbody and use rb.addVelocity.

Unity: getting NullReferenceException using javascript

I'm a newby in Unity and I'm following the first Unity tutorial. When i try to run my first script i get this error:
NullReferenceException: Object reference not set to an instance of an object
Here is my script:
#pragma strict
private var rb:Rigidbody;
private var player:GameObject;
function start() {
player = GameObject.Find("Player");
rb = player.GetComponent(Rigidbody);
}
function FixedUpdate() {
var moveHorizontal:float = Input.GetAxis("Horizontal");
var moveVertical:float = Input.GetAxis("Vertical");
var movement:Vector3 = new Vector3(moveHorizontal , 0.0f , moveVertical);
rb.AddForce(movement);
}
I have no idea what am I doing wrong.
UPDATE:
Here is my scene:
UPDATE:
I've put print in both functions, and it seems like start is not being called at all, and that is why my variable is not being initialized. Any idea?
I would remove the declaration
private var rb:Rigidbody;
because it seems that your script is trying to access the declared Rigidbody (that stills not initialized, so it's null), and not the object's real one.
Side note: seems that, from Unity 5.3.3, you have to do:
player.GetComponent.<Rigidbody>();
(from here)
It seems your gameobject doesn't have Rigidbody component attached to it and variable rb is null after rb = GetComponent(Rigidbody);
You should take advantage of "Unity way" to reference variables. I mean, your player and rb attributes must be public and you just drag into it your gameobject from hierarchy to your attribute on inspector.
If you still want to do it private, for some good reason, just change player = GameObject.Find("Player"); for player = GameObject.FindWithTag("Player"); and your null reference probably will be solved.
So finally after a few hours, I got it. The problem was that start function should be upper case Start. Since it was lowercase, it wasn't called and rb was not initialized.
And here is the final script:
#pragma strict
private var rb:Rigidbody;
function Start() {
rb = GetComponent(Rigidbody);
}
function FixedUpdate() {
var moveHorizontal:float = Input.GetAxis("Horizontal");
var moveVertical:float = Input.GetAxis("Vertical");
var movement:Vector3 = new Vector3(moveHorizontal , 0.0f , moveVertical);
rb.AddForce(movement);
}

unity2d instantiate prefab animator working partly

okay so my enemies are being instantiated in my main.js
but the animator is attached to this prefab of enemy ( it is a sprite animation )
it works on certian enemies
for instance
0will work
1 wont work
1,1,0,1,0,1,0,0,0,1,0,1,0 and so on it seems random
also my enemies spawn between 6 and 9 seconds.
i just cant figure this out
one problem after another.:( (guess this sums up a beginers game dev).
nearly done though.
thanks for your help stackoverflow community.
#pragma strict
var enemy : GameObject;
var speed : float = 1.0;
var enemanim : Animator;
var isdying : boolean = false;
function Start () {
this.transform.position.x = 8.325;
this.transform.position.y = -1.3;
enemanim = GetComponent(Animator);
enemanim.SetFloat("isdead",0);
}
function OnCollisionEnter2D(coll: Collision2D) {
if(coll.gameObject.CompareTag("distroy")){
Destroy(enemy.gameObject);
}
if(coll.gameObject.CompareTag("Player") && main.jumped == true){
isdying=true;
}
}
function Update () {
this.transform.Translate(Vector3(Input.GetAxis("Horizontal") * speed * Time.deltaTime, 0, 0));
this.rigidbody2D.velocity = Vector2(-5,0);
if (isdying==true){
enemanim.SetFloat("isdead",1);
}
}
You are missing
enemanim.Play();
It is working on and off because some of your Enemies are set to play automatically through the Editor.

SmoothFollow2D tweak

I've applied this standard assets script to my camera for a 2D game and it's actually doing a good job but since my background texture is placed inside a quad that "follows" the player and not the camera at higher movement speed the camera gets too far or too much behind the player and gets out of view.
Since I never programmed in JS I'd like to ask you how should I tweak this code to stop the script from moving the camera if the velocity is over (for example) 5f.
I tried to change it this way :
var target : Transform;
var smoothTime = 0.3;
private var thisTransform : Transform;
private var velocity : Vector2;
function Start()
{
thisTransform = transform;
}
function Update()
{
if(velocity.x > 5f) //in C# I'd do it this way, but apparently
velocity.x = 5f; //this is not stopping the camera from getting out of game-sight
thisTransform.position.x = Mathf.SmoothDamp( thisTransform.position.x,
target.position.x, velocity.x, smoothTime);
thisTransform.position.y = Mathf.SmoothDamp( thisTransform.position.y,
target.position.y, velocity.y, smoothTime);
}
This possibly happens because i'm actually passing a reference as a parameter (velocity.x called as a reference http://docs.unity3d.com/Documentation/ScriptReference/Mathf.SmoothDamp.html)
I am not sure if I understand you correctly.
If you want to set your camera's max speed, Mathf.SmoothDamp() can set maxSpeed.
var maxSpeed : float = 5.0f;
Mathf.SmoothDamp(transform.position.x, target.position.x, velocity.x, smoothTime, maxSpeed);