Unity HingeJoint have weird behavior in autogeneration problem with rotation? - c#

I am a beginner and I have cube in air with element attached him with no rotation like a node, i have a couple cubes for simulate rope with hint joint. I have clicking right click at a cube and spawn rope from direction player to node and attaching last element rope with player and this working very well. When player doesn't have velocity, and blocked rotation on rigidbody elements. But sometimes if I have been jumped and try to spawn rope in moving elements rope have weird rotations, and sometimes cubes rotation blocks. How could I work with rotations rope or I don't know, any advice? Thanks.
PS: sorry for my bad English.
private void CheckMouseActivity()
{
float x = Input.mousePosition.x;
float y = Input.mousePosition.y;
float z = Input.mousePosition.z;
Vector3 point = new Vector3(x, y, z);
if (Input.GetMouseButton(1) && !m_ropeIsActive)
{
m_aiming = true;
Ray ray = Camera.main.ScreenPointToRay(point);
GenerateRope(ray);
}
if (Input.GetButton("Jump") && m_ropeIsActive)
{
for (int i = 0; i < rope.Count; i++)
{
DestroyImmediate(rope[i]);
//rope[i].active = false;
}
playerRb.AddForce(new Vector3(6f, 6f), ForceMode.Impulse);
m_ropeIsActive = false;
m_hooked = false;
}
// check bounds in playing area
}
void GenerateRope(Ray ray)
{
layerMask = ~layerMask;
if (Physics.Raycast(ray, out RaycastHit hit, 10f, layerMask))
{
if (hit.transform.CompareTag("node") && !m_ropeIsActive)
{
activeHook = hit.transform.gameObject;
m_CanMove = false;
Vector3 hitPos = hit.transform.position;
Transform hook = hit.transform.GetChild(0);
Vector3 hookInverseNormal = hook.up * -1f;
Rigidbody previosRb = hit.transform.GetChild(0).GetComponent<Rigidbody>();//hook
Vector3 distanceFromNode = transform.position - hit.point;
int distance = (int)distanceFromNode.magnitude;
BoxCollider link = linkPrefub.GetComponent<BoxCollider>();
int length = (int)((distance - 1f) / sizeCell);
float ropeLength = sizeCell * 10f;
if (length < minLength)
{
length = minLength;
}
//else if (length > ropeLength)
//{
// length = (int)ropeLength * 2;
//}
for (int i = 1; i < length - 1; i++)
{
var t = sizeCell * i; //позиция под новый куб
Vector3 dirToPlayer = transform.position - hit.transform.position;
Vector3 newPos = dirToPlayer.normalized * t;
GameObject toInstantiate = Instantiate(linkPrefub, hit.transform.position + new
Vector3(newPos.x, -t, default), Quaternion.identity, hit.transform);
rope.Add(toInstantiate);
HingeJoint joint = toInstantiate.GetComponent<HingeJoint>();
if (i == 1)
{
joint.autoConfigureConnectedAnchor = true;
}
else
{
joint.autoConfigureConnectedAnchor = false;
joint.connectedAnchor = new Vector3(0f, -0.4f);
}
joint.enableCollision = false;
joint.connectedBody = previosRb;
previosRb = toInstantiate.GetComponent<Rigidbody>();
}
m_ropeIsActive = true;
m_hooked = true;
m_CanMove = true;
}
}
else
{
// what to do if not did hit
}
}
void FixedUpdate()
{
if (m_ropeIsActive)
{
if (m_hooked && activeHook)
{
//TODO крутить нод хука чтобы выглядило красиво
}
if (rope.Count != 0)
{
Rigidbody lastElementRope = rope[rope.Count - 1].GetComponent<Rigidbody>();
if (lastElementRope)
{
HingeJoint joint = GetComponent<HingeJoint>();
//joint.autoConfigureConnectedAnchor = false;
//joint.connectedBody = lastElementRope;
//joint.anchor = Vector2.zero;
//joint.connectedAnchor = new Vector2(0f, -0.4f);
}
}
}
}
Can put code from github with project.
I experimented here trying to achieve obedience, but I am convinced that this is the wrong direction, I just do not know how to work with rotations, I got confused
if (i == 1)
{
joint.autoConfigureConnectedAnchor = true;
}
else
{
joint.autoConfigureConnectedAnchor = false;
joint.connectedAnchor = new Vector3(0f, -0.4f);
}
GitHub https://github.com/Heges/first-2d-platformer/tree/main/2D-platformer

i am not sure but
void GenerateRope(Ray ray)
{
layerMask = ~layerMask;
if (Physics.Raycast(ray, out RaycastHit hit, 10f, layerMask))
{
Vector3 direction = transform.position - hit.transform.position;
if (direction.magnitude <= sizeOfRope)
{
if (hit.transform.CompareTag("node") && !m_ropeIsActive)
{
activeHook = hit.transform.gameObject;
m_CanMove = false;
Transform hook = hit.transform.GetChild(0);
Vector3 hookInverseNormal = hook.up * -1f;
float dot = Vector3.Dot(hookInverseNormal, ray.direction.normalized);
Debug.Log(dot);
Quaternion rotation = hit.transform.rotation;
Rigidbody previosRb = hit.transform.GetChild(0).GetComponent<Rigidbody>();//hook
Vector3 distanceFromNode = transform.position - hit.point;
int distance = (int)distanceFromNode.magnitude;
BoxCollider link = linkPrefub.GetComponent<BoxCollider>();//(int)link.size.magnitude / 2;
int length = (int)((distance - 1f) / sizeCell); //size of cell rope -1f размер игрока
float ropeLength = sizeCell * sizeOfRope;
if (length < minLength)
{
length = minLength;
}
//else if (length > ropeLength) // и слишком длинных
//{
// length = (int)ropeLength * 2;
//}
for (int i = 1; i < length - 1; i++)
{
var t = sizeCell * i; //позиция под новый куб
Vector3 dirToPlayer = transform.position - hit.transform.position;//направление до игрока,
Vector3 newPos = dirToPlayer.normalized * t;
GameObject toInstantiate = Instantiate(linkPrefub, hit.transform.position + new Vector3(newPos.x, -t, default), Quaternion.identity, hit.transform);
rope.Add(toInstantiate);
HingeJoint joint = toInstantiate.GetComponent<HingeJoint>();
joint.anchor = Vector2.up;
joint.connectedAnchor = new Vector2(0f, -0.4f);
joint.connectedBody = previosRb;
previosRb = toInstantiate.GetComponent<Rigidbody>();
}
m_ropeIsActive = true;
m_hooked = true;
}
}
else
{
//what to do if not did hit
}
}
it is still don't work very well but.like my problem is solved.
limited the distance from which the rope can be summoned, and as it turned out, when autogenerating parts of the rope, the Hint Joint defaults to its values ​​such as AutoAnchor. disabling them during creation, it seems that everything seems to work as it should
HingeJoint joint = toInstantiate.GetComponent<HingeJoint>();
joint.anchor = Vector2.up;
joint.connectedAnchor = new Vector2(0f, -0.4f);
joint.connectedBody = previosRb;
previosRb = toInstantiate.GetComponent<Rigidbody>();

Related

Grappling hook joint won't hook onto a game object Unity

I've started trying to code a grappling hook in unity but my distance joint won't hook onto the gameobject but rather blank space. I want to make it so that my distance joint will hook onto the gameobject instead of blank space. I feel that maybe there is a problem with the joint vectors but I don't know.
Here's my code:
public class Grapplescript : MonoBehaviour
{
public LineRenderer line;
DistanceJoint2D joint;
Vector3 targetPos;
RaycastHit2D hit;
public float distance = 10f;
public LayerMask mask;
public float step = 0.02f;
// Use this for initialization
void Start()
{
joint = GetComponent<DistanceJoint2D>();
joint.enabled = false;
line.enabled = false;
}
// Update is called once per frame
void Update()
{
if (joint.distance > .5f)
joint.distance -= step;
else
{
line.enabled = false;
joint.enabled = false;
}
if (Input.GetKeyDown(KeyCode.Mouse1))
{
targetPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
targetPos.z = 0;
hit = Physics2D.Raycast(transform.position, targetPos - transform.position, distance, mask);
if (hit.collider != null && hit.collider.gameObject.GetComponent<Rigidbody2D>() != null)
{
joint.enabled = true;
// Debug.Log (hit.point - new Vector2(hit.collider.transform.position.x,hit.collider.transform.position.y);
Vector2 connectPoint = hit.point - new Vector2(hit.collider.transform.position.x, hit.collider.transform.position.y);
connectPoint.x = connectPoint.x / hit.collider.transform.localScale.x;
connectPoint.y = connectPoint.y / hit.collider.transform.localScale.y;
Debug.Log(connectPoint);
joint.connectedAnchor = connectPoint;
joint.connectedBody = hit.collider.gameObject.GetComponent<Rigidbody2D>();
// joint.connectedAnchor = hit.point - new Vector2(hit.collider.transform.position.x,hit.collider.transform.position.y);
joint.distance = Vector2.Distance(transform.position, hit.point);
line.enabled = true;
line.SetPosition(0, transform.position);
line.SetPosition(1, hit.point);
//reference to another code
line.GetComponent<roperatio>().grabPos = hit.point;
}
}
//line.SetPosition(1, joint.connectedBody.transform.TransformPoint(joint.connectedAnchor));
if (Input.GetKey(KeyCode.Mouse1))
{
line.SetPosition(0, transform.position);
}
if (Input.GetKeyUp(KeyCode.Mouse1))
{
joint.enabled = false;
line.enabled = false;
}
}
}

How to keep object rotating in direction of touch movement?

I am looking for following implementation in unity based touch game:
I need object to rotate with the touch so it can be viewed from all sides(As long as touch is moving)
The object should keep on rotating in direction of previous touch
movement (when touch ends)
I tried implementing below code. But rotation is quiet quirky. It sometime rotates too fast sometimes in opposite direction of the swipe etc.
Here is what i have tried:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Functionalities : MonoBehaviour
{
public GameObject m_objecttorotate;
Vector3 localAngle;
[SerializeField]
float rotateSpeed = 0.09f;
Touch touchZero;
Vector3 rotateAxis;
float newMouseYpos = 0;
float prevMouseYpos = 0;
bool isIncreasing;
bool isDecreasing;
bool rotateManually;
void Update()
{
if (Input.touchCount > 0)
{
touchZero = Input.GetTouch(0);
//Rotate the model based on offset
localAngle = m_objecttorotate.transform.localEulerAngles;
localAngle.y -= rotateSpeed * touchZero.deltaPosition.x;
m_objecttorotate.transform.localEulerAngles = localAngle;
if (touchZero.deltaPosition != Vector2.zero)
{
rotateAxis = touchZero.deltaPosition;
}
}
else
{
localAngle.y += rotateSpeed * rotateAxis.y;
m_objecttorotate.transform.localEulerAngles = localAngle;
}
CheckIfTouchIsMovingUpOrDown();
if (isIncreasing)
{
Vector3 newPos = new Vector3(m_objecttorotate.transform.position.x, -0.25f, m_objecttorotate.transform.position.z);
m_objecttorotate.transform.position = Vector3.Lerp(m_objecttorotate.transform.position, newPos, 1 * Time.deltaTime);
}
else if (isDecreasing)
{
Vector3 newPos = new Vector3(m_objecttorotate.transform.position.x, 0.25f, m_objecttorotate.transform.position.z);
m_objecttorotate.transform.position = Vector3.Lerp(m_objecttorotate.transform.position, newPos, 1 * Time.deltaTime);
}
else
{
Vector3 newPos = new Vector3(m_objecttorotate.transform.position.x, 0f, m_objecttorotate.transform.position.z);
m_objecttorotate.transform.position = Vector3.Lerp(m_objecttorotate.transform.position, newPos, 1 * Time.deltaTime);
}
}
void CheckIfTouchIsMovingUpOrDown()
{
if (Input.GetMouseButton(0))
{
if (prevMouseYpos != newMouseYpos)
{
if (prevMouseYpos < newMouseYpos + 1f)
{
isIncreasing = true;
isDecreasing = false;
Debug.Log("Increasing");
prevMouseYpos = newMouseYpos;
}
else if (prevMouseYpos > newMouseYpos - 1f)
{
isDecreasing = true;
isIncreasing = false;
Debug.Log("Decreasing");
prevMouseYpos = newMouseYpos;
}
}
newMouseYpos = Input.mousePosition.y;
}
else
{
//isDecreasing = false;
// isIncreasing = false;
prevMouseYpos = newMouseYpos;
}
}
}

Still not clear yet why all the ships are not moving to the direction they are facing after rotation?

private void MoveShips()
{
for (int index = 0; index < spheres [0].transform.childCount; index++) {
Transform oneChild = spheres [0].transform.GetChild (index);
lastPositions [index] = oneChild.transform.position;
if (!hasRotated [index])
{
oneChild.transform.position += Vector3.forward * Time.deltaTime * moveSpeed;
}
else
{
oneChild.transform.position += oneChild.transform.forward * Time.deltaTime * moveSpeed;
}
}
if (updateOn == true) {
for(int index =0;index < spheres[0].transform.childCount;index++)
{
Transform child = spheres[0].transform.GetChild(index);
distanceTraveled[index] += Vector3.Distance (child.transform.position, lastPositions [index]);
if (distanceTraveled [index] >= randomNumbers [index] && !hasRotated [index])
{
targetAngles = child.transform.eulerAngles + 180f * Vector3.up;
StartCoroutine (TurnShip (child.transform, child.transform.eulerAngles, targetAngles, smooth));
hasRotated [index] = true;
}
}
}
}
IEnumerator TurnShip(Transform ship, Vector3 startAngle, Vector3 endAngle, float smooth)
{
float lerpSpeed = 0;
while(lerpSpeed < 1)
{
ship.eulerAngles = Vector3.Lerp(startAngle, endAngle, lerpSpeed);
lerpSpeed += Time.deltaTime * smooth;
yield return null;
}
}
For example i have 300 ships. They are moving forward using Vector3.forward then i want to make that after each child completed the rotation then change it's moving direction to the direction it's facing now. So in the case i rotate the ships 180 degrees but the ships move up.
This line make them move up:
oneChild.transform.position += oneChild.transform.forward * Time.deltaTime * moveSpeed;
I tried also to change this line to:
oneChild.transform.position += oneChild.transform.forward * moveSpeed;
This make the ships to disapear.
I also tried:
oneChild.transform.position += oneChild.transform.forward * -1 * moveSpeed;
Or
oneChild.transform.position += -oneChild.transform.forward * Time.deltaTime * moveSpeed; --- This line make the ships move up turn and move down. But i want them to move forward not up and down. Move forward to the direction they are facing after the rotation.
Or
oneChild.transform.position += oneChild.transform.forward * -1;
I also tried to use only the Vector3 for example:
if (!hasRotated [index])
{
oneChild.transform.position += Vector3.forward * Time.deltaTime * moveSpeed;
}
else
{
oneChild.transform.position += Vector3.back * Time.deltaTime * moveSpeed;
}
But this will move the ships back not to the direction they are facing. If i will rotate the ships only 60 degrees they will move back not to the facing direction.
Another problem i think it's a problem the ships change the moving diection if it's up down before they completed the rotation. I want that first the ship each ship will complete the rotation and while rotating to keep moving to the original direction only when the rotation end then change the movement to the direction it's facing.
The script
using System;
using UnityEngine;
using Random = UnityEngine.Random;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class SphereBuilder : MonoBehaviour
{
public GameObject SpaceShip;
GameObject[] spheres;
public float moveSpeed = 50;
private float distanceTravelled;
public bool updateOn = true;
private Vector3 lastPosition;
List<bool> hasRotated = new List<bool>();
List<float> distanceTraveled = new List<float>();
List<Vector3> lastPositions = new List<Vector3>();
List<int> randomNumbers = new List<int> ();
public float smooth = 1f;
private Vector3 targetAngles;
private bool isRunning = false;
// for tracking properties change
private Vector3 _extents;
private int _sphereCount;
private float _sphereSize;
/// <summary>
/// How far to place spheres randomly.
/// </summary>
public Vector3 Extents;
/// <summary>
/// How many spheres wanted.
/// </summary>
public int SphereCount;
public float SphereSize;
private void rndNumbers()
{
int Min = 20;
int Max = 50;
System.Random rnd = new System.Random ();
randomNumbers = Enumerable.Range(Min, Max).OrderBy(x => rnd.Next()).Take(spheres[0].transform.childCount).ToList();
}
private void Start()
{
UpdateSpheres ();
spheres = GameObject.FindGameObjectsWithTag("MySphere");
rndNumbers ();
for(int index = 0; index < spheres[0].transform.childCount;index++)
{
Transform child = spheres[0].transform.GetChild(index);
lastPosition = new Vector3(child.transform.position.x,child.transform.position.y,child.transform.position.z);
lastPositions.Add (lastPosition);
hasRotated.Add(false);
distanceTraveled.Add(0f);
}
}
private void OnValidate()
{
// prevent wrong values to be entered
Extents = new Vector3(Mathf.Max(0.0f, Extents.x), Mathf.Max(0.0f, Extents.y), Mathf.Max(0.0f, Extents.z));
SphereCount = Mathf.Max(0, SphereCount);
SphereSize = Mathf.Max(0.0f, SphereSize);
}
private void Reset()
{
Extents = new Vector3(250.0f, 20.0f, 250.0f);
SphereCount = 100;
SphereSize = 20.0f;
}
private void Update()
{
UpdateSpheres();
MoveShips ();
}
private void MoveShips()
{
for (int index = 0; index < spheres [0].transform.childCount; index++) {
Transform oneChild = spheres [0].transform.GetChild (index);
lastPositions [index] = oneChild.transform.position;
if (!hasRotated [index])
{
oneChild.transform.position += Vector3.forward * Time.deltaTime * moveSpeed;
}
else
{
oneChild.transform.position += Vector3.back * Time.deltaTime * moveSpeed;
}
}
if (updateOn == true) {
for(int index =0;index < spheres[0].transform.childCount;index++)
{
Transform child = spheres[0].transform.GetChild(index);
distanceTraveled[index] += Vector3.Distance (child.transform.position, lastPositions [index]);
if (distanceTraveled [index] >= randomNumbers [index] && !hasRotated [index]) {
//child.transform.Rotate (new Vector3 (0f, 180f, 0f));
targetAngles = child.transform.eulerAngles + 180f * Vector3.up;
//if (!isRunning)
//{
StartCoroutine (TurnShip (child.transform, child.transform.eulerAngles, targetAngles, smooth));
//}
hasRotated [index] = true;
child.transform.position += Vector3.back * Time.deltaTime * moveSpeed;
}
}
}
}
IEnumerator TurnShip(Transform ship, Vector3 startAngle, Vector3 endAngle, float smooth)
{
isRunning = true;
float lerpSpeed = 0;
while(lerpSpeed < 1)
{
ship.eulerAngles = Vector3.Lerp(startAngle, endAngle, lerpSpeed);
lerpSpeed += 1 * smooth;
yield return new WaitForSeconds(0.01f);
}
isRunning = false;
}
private void UpdateSpheres()
{
if (Extents == _extents && SphereCount == _sphereCount && Mathf.Approximately(SphereSize, _sphereSize))
return;
// cleanup
var spheres = GameObject.FindGameObjectsWithTag("Sphere");
foreach (var t in spheres)
{
if (Application.isEditor)
{
DestroyImmediate(t);
}
else
{
Destroy(t);
}
}
var withTag = GameObject.FindWithTag("Terrain");
if (withTag == null)
throw new InvalidOperationException("Terrain not found");
for (var i = 0; i < SphereCount; i++)
{
var o = Instantiate(SpaceShip);
o.tag = "Sphere";
o.transform.SetParent(gameObject.transform);
o.transform.localScale = new Vector3(SphereSize, SphereSize, SphereSize);
// get random position
var x = Random.Range(-Extents.x, Extents.x);
var y = Extents.y; // sphere altitude relative to terrain below
var z = Random.Range(-Extents.z, Extents.z);
// now send a ray down terrain to adjust Y according terrain below
var height = 10000.0f; // should be higher than highest terrain altitude
var origin = new Vector3(x, height, z);
var ray = new Ray(origin, Vector3.down);
RaycastHit hit;
var maxDistance = 20000.0f;
var nameToLayer = LayerMask.NameToLayer("Terrain");
var layerMask = 1 << nameToLayer;
if (Physics.Raycast(ray, out hit, maxDistance, layerMask))
{
var distance = hit.distance;
y = height - distance + y; // adjust
}
else
{
Debug.LogWarning("Terrain not hit, using default height !");
}
// place !
o.transform.position = new Vector3(x, y, z);
}
_extents = Extents;
_sphereCount = SphereCount;
_sphereSize = SphereSize;
}
}
what you are saying makes me think the local forward is simply wrong (your ship model is turned). or your forward gets changed because of parenting (wich can be tricky)
also
dont use Vector3.forward, if you want to travel on it OWN forward.
oneChild.transform.position += oneChild.transform.forward * Time.deltaTime * moveSpeed;
is correct.
x
ship.eulerAngles = Vector3.Lerp(startAngle, endAngle, lerpSpeed);
should be a Slerp
https://docs.unity3d.com/ScriptReference/Vector3.Slerp.html
The difference between this and linear interpolation (aka, "lerp") is that the vectors are treated as directions rather than points in space.
or lerp angle:
https://docs.unity3d.com/ScriptReference/Mathf.LerpAngle.html
x
targetAngles = child.transform.eulerAngles + 180f * Vector3.up;
i find this last line a bit abstract, not knowing what angle you are turning on, and ,again, using vector3.up instead of child.transform.up
but i guess this line is to flip your ship upside down, or perhaps making it move up&down
hope it helps.

Falling Respawn

Im making a platform game with Unity and Im programming with C#. I have a Ball Control script which handles the input and the physics behind its continuous bouncing. I also have a BounceTrigger script which make the ball stop and then make it bounce again. Im trying to implement a respawn with the player should be respawning at the last platform not destructible he has bounced over.
Ball Control Script
public float velocity = 2;
bool alreadyBounced;
bool boost;
float boostMultiplier;
Vector3 boostVelocityAdd;
int fallY = 10;
BounceTrigger platform;
// Update is called once per frame
void Update ()
{
alreadyBounced = false;
float appliedVelocity = velocity * (boost ? boostMultiplier : 1);
Vector3 direction = Vector3.zero;
if(Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.A)) { direction = Vector3.left; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange);}
if(Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D)) { direction = Vector3.right; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange);}
if(Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.W)) { direction = Vector3.forward; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange);}
if(Input.GetKeyDown(KeyCode.DownArrow) || Input.GetKeyDown(KeyCode.S)) { direction = -Vector3.forward; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange); }
if(Input.GetKeyUp(KeyCode.LeftArrow) || Input.GetKeyUp(KeyCode.A)) { direction = -Vector3.left; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange); }
if(Input.GetKeyUp(KeyCode.RightArrow) || Input.GetKeyUp(KeyCode.D)){ direction = -Vector3.right; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange); }
if(Input.GetKeyUp(KeyCode.UpArrow) || Input.GetKeyUp(KeyCode.W)) { direction = -Vector3.forward; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange); }
if(Input.GetKeyUp(KeyCode.DownArrow) || Input.GetKeyUp(KeyCode.S)) { direction = Vector3.forward; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange); }
CheckFalling ();
}
public void CheckFalling(){
if(this.transform.position.y < fallY){
Respawn();
}
}
public void Respawn(){
this.transform.position = lastPlatform.transform.position + Vector3.up;
}
public void Bounce(BounceTrigger platform, float upVelocity) {
var reboteGO = (GameObject) GameObject.FindWithTag ("TextoRebote");
var reboteComp = reboteGO.GetComponent<BounceCounter>();
if(!alreadyBounced)
{
if(!platform.isDestructible){
lastPlatform = platform;
}
Debug.Log("Bounce");
alreadyBounced = true;
reboteComp.AumentarRebote();
float downVelocity = rigidbody.velocity.y;
rigidbody.AddForce(Vector3.up * (-downVelocity + upVelocity), ForceMode.VelocityChange);
ResetBoost();
}
}
public void Boost(float multiplier){
if(!boost){
Debug.Log("Boost");
StartCoroutine(BoostCoroutine(multiplier));
}
}
public void ResetBoost(){
if(boost){
Debug.Log("Reset boost");
boost = false;
Vector3 velocityAdd = rigidbody.velocity;
velocityAdd.x = velocityAdd.x / boostMultiplier * (boostMultiplier - 1);
velocityAdd.z = velocityAdd.z / boostMultiplier * (boostMultiplier - 1);
velocityAdd.y = 0;
rigidbody.AddForce(-velocityAdd, ForceMode.VelocityChange);
}
}
public void RestarVida(){
var vidaGO = (GameObject) GameObject.FindWithTag ("TextoVida");
var vidaComp = vidaGO.GetComponent<LifeCounter>();
vidaComp.RestarVida ();
}
IEnumerator BoostCoroutine(float multiplier){
yield return 0;
yield return new WaitForFixedUpdate();
boost = true;
boostMultiplier = multiplier;
Vector3 velocityAdd = rigidbody.velocity;
Debug.Log(velocityAdd);
velocityAdd.x = velocityAdd.x * (boostMultiplier - 1);
velocityAdd.z = velocityAdd.z * (boostMultiplier - 1);
velocityAdd.y = 0;
rigidbody.AddForce(velocityAdd, ForceMode.VelocityChange);
Debug.Log(velocityAdd);
}
Bounce Trigger script:
`
public float upVelocity = 10;
public bool isDestructible = false;
public virtual void OnTriggerEnter(Collider collider){
collider.GetComponent<BallControl>().Bounce(this, upVelocity);
}
when I compile this I get a nullReferenceException
`
You have a global variable BounceTrigger platform; instead of BounceTrigger lastPlatform;, so lastPlatform don't exists anywhere in your code.

Unity3D transform.position.x keeps setting to 0

The weirdest thing keeps happening and I can not figure out why. Instead of just setting up like 20 different prefabs, I wanted to instatiate them in my code. I am making a Space Invaders C# game and I got the first row of invaders to spawn fine using the code found below. Literally no issues at all, and they move how I want them too as well. But as soon as I set up my second row the transform.position syntax that I used for the first row, suddenly does not apply and it just sets my transform.position.x to 0. I do have another class that MIGHT be the reason, but so far I have not found any solution to this problem. Thanks for help in advance.
//GameController Class
//
//globals
//
Quaternion roto;
public Vector3 newPos;
public float addInvader
bool spawnInvader = true;
public GameObject invaders;
//
void Update()
{
newPos = transform.position;
roto = transform.rotation;
newPos2 = transform.position;
roto2 = transform.rotation;
if (addInvader <= 0f)
{
SpawnInvaders ();
}
if (addInvader > 0f)
{
SpawnInvaders ();
}
if (addInvader > 5f)
{
spawnInvader = false;
}
if (add2Invader <= 0f)
{
//invaderSrow();
}
if (add2Invader > 0f)
{
//invaderSrow();
secondrow = false;
}
}
void SpawnInvaders()
{
if (spawnInvader)
{
if (addInvader < 1f)
{
newPos.x = 900f;
newPos.y = 0f;
newPos.z = 800f;
roto.z = 180f;
Instantiate (invaders, newPos, roto);
addInvader++;
}
if (addInvader == 1f)
{
newPos.x = 700f;
newPos.y = 0f;
newPos.z = 800f;
roto.z = 180f;
Instantiate (invaders, newPos, roto);
addInvader++;
}
if (addInvader == 2f)
{
newPos.x = 500f;
newPos.y = 0f;
newPos.z = 800f;
roto.z = 180f;
Instantiate (invaders, newPos, roto);
addInvader++;
}
if (addInvader == 3f)
{
newPos.x = 300f;
newPos.y = 0f;
newPos.z = 800f;
roto.z = 180f;
Instantiate (invaders, newPos, roto);
addInvader++;
}
if (addInvader == 4f)
{
newPos.x = 100f;
newPos.y = 0f;
newPos.z = 800f;
roto.z = 180f;
Instantiate (invaders, newPos, roto);
addInvader++;
}
if (addInvader == 5f)
{
newPos.x = -600f;
//newPos2.x = newPos2.x - 200f;
newPos.y = 0f;
newPos.z = 500f;
roto.z = 180f;
Instantiate (invaders, newPos, roto);
addInvader++;
}
}
return;
}
void invaderSrow()
{
InvaderController F = new InvaderController();
//F.newX = newPos2.x;
if (secondrow)
{
if (add2Invader < 1f)
{
newPos.x = -800f;
newPos.y = 0f;
newPos.z = 500f;
roto.z = 180f;
//Instantiate (invaders2, newPos, roto);
add2Invader++; //add2Invader should be 1 now....
//secondrow = false;
}
if (add2Invader == 1f)
{
newPos2 = transform.position;
newPos2.x = -800f + 200f;
//F.newX = -800f;
//F.newX = newPos2.x + 200f;
newPos2.y = 0f;
newPos2.z = 500f;
roto2.z = 180f;
//Instantiate (invaders3, newPos2, roto2);
add2Invader++;
}
}
return;
}
//InvaderController class
//
//globals
//
public float newX;
public float invaderSpeed;
public float resistance;
public GameObject Invader;
public GameObject explosion;
Quaternion rotation;
//
void Awake()
{
firstxoff = true;
}
// Update is called once per frame
void Update ()
{
if (firstxoff == true)
{
firstmove ();
}
moveX1 ();
}
void firstmove()
{
Vector3 newPos = transform.position;
newPos.x -= invaderSpeed;
transform.position = newPos;
if (newPos.x < -900f) //moves z
{
Vector3 newPosZ = transform.position;
newPosZ.z -= invaderSpeed;
float x = -900f;
newX = x;
newPosZ.x = newX;
transform.position = newPosZ;
}
}
void moveX1()
{
Vector3 newPos = transform.position;
if (newPos.z <= 500f)
{
Vector3 newPosX = transform.position;
newX = newX + invaderSpeed;
float z = 500f;
newZ = z;
newPosX.z = newZ;
newPosX.x = newX;
transform.position = newPosX;
if (newPosX.x > -900f)
{
newX = newX + (invaderSpeed + 7f);
firstxoff = false;
}
}
}
in moveX1() you are using newX , is it possible you are sometimes calling moveX1 before firstMove ? if so then newX would be undefined and 0.
Figured it out. Added a newX = newPosX.x; line at the start of my moveX1() function :D thanks everyone who tried!

Categories

Resources