7
\$\begingroup\$

I'm making another simple game, a catch game, where a spawning target game object must be captured using a skewer to impale it. Here how:

  1. At the start, the falling object (in red) will fall in a vertical direction (in blue) enter image description here

  2. When aimed properly, the target will fall down along the line of the skewer. (in blue) Then, another target is spawned and will fall vertically. (in red) enter image description here

  3. When aimed successfully again in a streak, the second target will fall along the skewer and stacked. Same process over and over when another target is spawned. enter image description here

However, when I test run it on the scene tab in Unity, when impaled several targets, instead of a smooth flow and stacking it ended up overlaying it instead of stacking it up like a pancake. Here's what it look like: enter image description here

As I noticed when reaching the half-way of my progress, I tried to figure out how to deal with collider bodies without sticking each other so that it will actually stack like in the example of the image at no. 3. Here's the script code I added in the target game object:

using UnityEngine;
using System.Collections;

public class ImpaleStateTest : MonoBehaviour {

    public GameObject target;
    public GameObject skewer;

    public bool drag = false;

    private float stack;
    private float impaleCount;

    void Start () {
        stack = 0;
        impaleCount = 0;
    }

    void Update () {
        if(drag) {
            target.transform.position = new Vector3 (DragTest.dir.transform.position.x, DragTest.dir.transform.position.y - 0.35f, 0);
            target.transform.rotation = DragTest.degrees;
            target.rigidbody2D.fixedAngle = true;
            target.rigidbody2D.isKinematic = true;
            target.rigidbody2D.gravityScale = 0;

            if(Input.GetMouseButton(0)) {
                Debug.Log ("Skewer: " + DragTest.dir.transform.position.x);
                Debug.Log ("Target: " + target.transform.position.x);
            }
        }
    }

    void OnTriggerEnter2D(Collider2D collider) {
        impaleCount++;
        Debug.Log ("Impaled " + impaleCount + " time(s)!");
        drag = true;
        audio.Play ();
    }

}

Aside from that, I'm not sure if it's right but, the only way to stick the impaled targets while dragging the skewer left or right is to get the X coordinates from the skewer only. Is there something else to recommend it in order to improve this behavior as realistic as possible? Please help.

\$\endgroup\$
1
\$\begingroup\$

You are using OnTriggerEnter2D, so i guess you are using triggers intead of colliders. Triggers don't get effected from collisions as oppose to colliders, instead, they send messages to scripts on it and colliding gameobject.

So, if you want your "circles" to collide, you should make them non-trigger.

\$\endgroup\$
0
\$\begingroup\$

Stacking Issue

Regarding the stacking issue, I am not sure how your class is setup, but I would consider handling the positioning of the stacked elements based on an indexed approach.

For Instance (pseudo code):

class Skewer : MonoBehaviour
{
   public List<SkewerElements> skewerElements = new List<SkewerElements>();
   public float skewerElementHeight = 1; // 

   public void UpdateSkewerPositions()
   {
       int count = skewerElements.Count; 
       float yOffset = count * skewerElementHeight; // use an offset to start

       for(int i = 0; i < count; i++)
       {
           // Basically by manipulating the yOffset you can "stack" elements based on the count of elements.
           skewerElements[i].transform.position = new Vector3(transform.position.x, transform.position.y + (-yOffset + (skewerElementHeight * i)), 0);
       }
   }
}

I used a negative yOffset because if the skewer y is 0. Then we move down the first element by the count of the skewerElements. Then we increment the y by the index of the element by its height.

\$\endgroup\$
0
\$\begingroup\$

Engines aside, circle collision is incredibly easy to program - you can do it from scratch. Every circle object must have a Vec2d position value and a radius.

In your update loop, iterate through your list of all circles and then test to see if any pos value of one, >= the pos of any other, + both radiai.

If this is true, stop the gravity force from acting on the circles that are touching. Or, you can implement a repelling force for the object moving. Mind you, if the the two forces (gravity and repell) have a difference of less than 1, you have to set both to zero, or they will vibrate.

You will want a Vec2d library for this, unless you want to run the vector math yourself (it's not that hard).

As for the skewer: since the only forces you are dealing with are gravity and collision, you don't have to worry about any complicated physics. The skewer is a line, so you can test it's collision by determining if any of the circles x or y are >= the skewer position.

This should all be pretty straight forward, comment if you need details.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.