Search Unity

New Physics-based Action Game

Discussion in 'Works In Progress - Archive' started by hidingspot, Sep 16, 2014.

  1. hidingspot


    Apr 27, 2011
    A new project from SuperChop Games

    For now, we're calling it proto-1. We'll be sharing unity specific details on this thread, as well as more general discussions on TIGSource here, and our blog here. For anyone who is interested, please share your thoughts. Links to payable builds coming soon!

    Recent screenshot:

    Key Features
    - Completely physics-based
    - 2d action platformer
    - Procedural weapon system
    - Roguey-like-ish-type

    - PC
    - Mac
    - Linux
    - Console
    - PS Vita
    Last edited: Oct 13, 2014
    FBTH likes this.
  2. marserMD


    Aug 29, 2014
    hi. As long as i understand, you can't control the character directly. If so, it's really cool. I've had the similar idea for an infinite runner.
    Maybe my plugin would be helpful for your explosions(it will be free, so it's not an advertisment)))
  3. hidingspot


    Apr 27, 2011
    You can control the character directly, but it's within the context of the physics engine. So, telling the character to move right applies a physics force in the right direction. At the end of the day, the goal is tight controls, but within the context of the physics engine, so that realistic dynamics effect every part of the gameplay (character movement included).
  4. hidingspot


    Apr 27, 2011
    Thought I'd share our implementation of a simple sandbox tool I created early on (well, it's still very early) in development. It's great for testing out scenarios and scene changes on the fly, from right within a running build of the game. First here's a little clip:

    The main piece of code is actually quite simple. It's called ObjectPlacer, and it does just that:

    Code (CSharp):
    1. using UnityEngine;
    3. public class ObjectPlacer : MonoBehaviour
    4. {
    5.    /// <summary>
    6.    /// Possible prefabs to be selected randomly
    7.    /// </summary>
    8.    public GameObject[] prefabs;
    9.    GameObject current;
    11.    void Update ()
    12.    {
    13.      if (prefabs.Length < 1) {
    14.        return;
    15.      }
    16.      // recreate a prefab to place if there is none
    17.      if (current == null) {
    18.        ReCreate ();
    19.      }
    20.      current.transform.position = transform.position;
    21.      if (Input.GetMouseButtonDown (0)) {
    22.        PlaceObject (current);
    23.      }
    24.    }
    26.    public void ReCreate ()
    27.    {
    28.      // handle when Unity UI calls methods in edit mode
    29.      if (!Application.isPlaying || !enabled || !gameObject.activeInHierarchy) {
    30.        return;
    31.      }
    32.      if (current != null) {
    33.        Destroy (current);
    34.      }
    35.      current = CreateObject (prefabs [Random.Range (0, prefabs.Length)]);
    36.    }
    38.    virtual protected void PlaceObject (GameObject go)
    39.    {
    40.      // let go of current object, setting it's position
    41.      // and signaling for a new one to be created
    42.      current = null;
    43.    }
    45.    virtual protected GameObject CreateObject (GameObject fromPrefab)
    46.    {
    47.      return Instantiate (fromPrefab) as GameObject;
    48.    }
    50.    void OnDisable ()
    51.    {
    52.      if (current != null) {
    53.        Destroy (current);
    54.      }
    55.    }
    56. }
    For each type of object/prefab you want to be able to place in the sceen, you'd have an ObjectPlacer object in the hierarchy which points to that prefab (or multiple to pull randomly):

    All the Unity UI does is set which ObjectPlacer is active/inactive on button toggle:

    One important note. You want to make sure that object placer's aren't active while hovering over buttons. Otherwise, anytime you select a new button, it will create any existing selected object at the location of that button. After some fumbling with the Rect class, I realized a much simpler way to achieve this. The new Unity UI automatically swallows events based on the GraphicRaycaster behaviour which is attached to the canvas. All we need to do is create a "placement area" panel/image behind the rest of the gui which turns the sandbox tools' parent on/off on pointer enter/exit. Though it is fully transparent, the image component is required to trigger the enter/exit events:

    Hope you find this useful!
    Last edited: Sep 30, 2014
  5. hidingspot


    Apr 27, 2011
    Here's a first look at the door that transports the player between it's cozy home base and the big bad game world.

    The idea is that between levels the player will be able to travel to his/her safe-home, wherein powerups, customizations, and other fun stuff can be configured.

    ludiares likes this.
  6. hidingspot


    Apr 27, 2011
    Oh dear, they're getting smarter...

    Little ground enemies now traverse and climb over obstacles towards their destination. In this case, toward an unsuspecting player character.

    Going to be traveling for several days, but I'll try to find time to write about the AI system. It's pretty cool.
  7. Myhijim


    Jun 15, 2012
    Surprised this hasn't been given much attention, it looks like a sweet little side-scroller.

    Those little things freak me out and the AI behind them seems solid.
  8. stoilcho


    Sep 8, 2014
    I'm digging the Geometry Wars stripped down graphics (proper name for those is ? ) and the ticks are looking awesomely creepy. I will totally provide detailed feedback once we have a web demo.

    I do have a question for OP and I'm sorry for watering down the thread, but OP stated:
    So, telling the character to move right applies a physics force in the right direction.
    I'm working on a top-down game that is not really physics based but I'm still using addForce and stuff like that to move the characters, projectiles and stuff around. Is that somehow bad practices if a game is not to be 'physics-based' ? Thanks guys
  9. hidingspot


    Apr 27, 2011
    I wouldn't say it's bad practice, as long as you're happy with the results. Most of the time, with character controllers especially, you'll see people set rigidbody velocity directly. Doing it that way gives somewhat more predicable results (you specify just how fast and in what direction the character moves). In my case, I wanted that degree of unpredictability, so that interesting physics interactions could bubble up immergently. Like in this early test where the player grabs a flying enemy and drags it to the ground. The only part of that interaction that was coded was the grab:
  10. hidingspot


    Apr 27, 2011
    Thanks, I'll definitely try to post about the AI in the next week. I'll include a gif of the load test I did with a whole bunch of those little creepers on the screen at once.
  11. hidingspot


    Apr 27, 2011
    Using Mecanim for AI State Machine

    I had begun using a simple state machine codebase from a previous project, but decided to try using Mecanim as a generic state machine. Having a visual state tool in the editor is a big aid to tackling complex AI. After seeing the announcement that Unity 5 will support state machine behaviours, I thought it would be nice to implement a wrapper solution in the meantime, which would not only allow the use of Mecanim state behaviours, but also easy migration when Unity 5 becomes available.

    The main class is call "MecanimWrapper". It associates mecanim states with Unity behaviours, and sets those behaviours enabled based on the active mecanim state.

    You can see that the names of the state behaviours listed in the Mecanim Wrapper match those seen in the screenshot of the Mecanim Animator state machine. So, when the state machine idle state starts, the AiGroundIdle script is enabled. When the state switches to chase, the AiGroundIdle script is disabled and the AiGroundChase script is enabled. All the while, the Animator windows gives a clear view of which state is active. Very handy for debugging and visualizing AI.

    So here's really the only thing you need to try it out yourself, the MecanimWrapper class (AiMecanimWrapper above is a basic extension of that class).

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    4. public class MecanimWrapper : MonoBehaviour
    5. {
    6.     public Animator animator;
    7.     public StateBehaviour[] stateBehaviours;
    8.     static int CURRENT_STATE_TIME = Animator.StringToHash ("currentStateTime");
    9.     Dictionary<int, Behaviour[]> behaviourCache;
    10.     int currentState;
    11.     float _currentStateTime;
    13.     float currentStateTime {
    14.         get {
    15.             return _currentStateTime;
    16.         }
    17.         set {
    18.             _currentStateTime = value;
    19.             animator.SetFloat (CURRENT_STATE_TIME, _currentStateTime);
    20.         }
    21.     }
    23.     void Start ()
    24.     {
    25.         behaviourCache = new Dictionary<int, Behaviour[]> ();
    26.         foreach (StateBehaviour item in stateBehaviours) {
    27.             int nameHash = Animator.StringToHash (item.layer + "." + item.state);
    28.             behaviourCache.Add (nameHash, item.behaviours);
    29.             SetBehavioursEnabled (item.behaviours, false);
    30.         }
    31.     }
    33.     void Update ()
    34.     {
    35.         currentStateTime += Time.deltaTime;
    36.         int state = animator.GetCurrentAnimatorStateInfo (0).nameHash;
    37.         if (state != currentState) {
    38.             ChangeState (state);
    39.         }
    40.     }
    42.     void ChangeState (int toState)
    43.     {
    44.         if (behaviourCache.ContainsKey (currentState)) {
    45.             SetBehavioursEnabled (behaviourCache [currentState], false);
    46.         }
    47.         if (behaviourCache.ContainsKey (toState)) {
    48.             SetBehavioursEnabled (behaviourCache [toState], true);
    49.         }
    50.         currentState = toState;
    51.         currentStateTime = 0f;
    52.     }
    54.     void SetBehavioursEnabled (Behaviour[] behaviours, bool enabled)
    55.     {
    56.         foreach (Behaviour behaviour in behaviours) {
    57.             behaviour.enabled = enabled;
    58.         }
    59.     }
    61.     [System.Serializable]
    62.     public class StateBehaviour
    63.     {
    64.         public string state;
    65.         public string layer = "Base Layer";
    66.         public Behaviour[] behaviours;
    67.     }
    68. }
    One important note: In these state machines, I'm using a transition time of 0. I'm not certain if states overlap during a transition with time > 0, so keep that in mind when creating your mecanim state machines.

    Hope you find this useful!
    Last edited: Oct 13, 2014
    RemDust and coingod like this.