Giter VIP home page Giter VIP logo

Comments (5)

saikyun avatar saikyun commented on June 1, 2024

I made a workaround to progress in the tutorial by creating an empty object and adding all GOs as children to it, and destroying all children on that GO when running setup again.


;; Game object to hold all generated objects
(def holder (object-named "Generated"))

(defn setup [parent]
  (doseq [child (children parent)]
    (destroy child))
  ;; Load the "fighter" prefab into the scene graph
  (let [player (GameObject/Instantiate (Resources/Load "fighter"))]
    (child+ holder player)
    ;; Set its name
    (set! (.name player) "player")))

from fighter-tutorial.

saikyun avatar saikyun commented on June 1, 2024

Here's a whole working example:

(ns fighter-tutorial.core
  (:use arcadia.core arcadia.linear)
  (:require [arcadia.sugar :as a]
            [arcadia.scene :as scn])
  (:import [UnityEngine Collider2D Physics
            GameObject Input Rigidbody2D
            Vector2 Mathf Resources Transform
            Quaternion
            Collision2D Physics2D]
           ArcadiaState))

(defn bearing-vector [angle]
  (let [angle (* Mathf/Deg2Rad angle)]
    (v2 (Mathf/Cos angle) (Mathf/Sin angle))))

(defn abs-angle [v]
  (* Mathf/Rad2Deg
     (Mathf/Atan2 (.y v) (.x v))))

(defn controller-vector []
 (v2 (Input/GetAxis "Horizontal")
     (Input/GetAxis "Vertical")))

(defn wasd-key []
  (or (Input/GetKey "w")
      (Input/GetKey "a")
      (Input/GetKey "s")
      (Input/GetKey "d")))

(defn move-forward [^Rigidbody2D rb, distance]
  (.MovePosition rb
    (v2+ (.position rb)
      (v2* (bearing-vector (.rotation rb))
           distance))))


(def player-bullets-layer (UnityEngine.LayerMask/NameToLayer "player-bullets"))
(def enemy-bullets-layer (UnityEngine.LayerMask/NameToLayer "enemy-bullets"))

(defn player-movement-fixed-update [obj k]
  (with-cmpt obj [rb Rigidbody2D]
    (when (wasd-key)
      (.MoveRotation rb (abs-angle (controller-vector)))
      (set! (.angularVelocity rb) 0)
      (.AddForce rb
                 (v2* (bearing-vector (.rotation rb))
                      3)))))

(def player-movement-role
  {:fixed-update #'player-movement-fixed-update})

(defrole health-role
  :state {:health 1}
  (update [obj k]
          (let [{:keys [health]} (state obj k)]
            (when (<= health 0)
              (destroy obj)))))

(defn damage [obj amt]
  (update-state obj ::health update :health - amt))

(defrole bullet-collision
  (on-trigger-enter2d [bullet, ^Collider2D collider, k]
                      (let [obj2 (.gameObject collider)]
                        (when (state obj2 ::health)
                          (damage obj2 1)
                          (destroy bullet)))))

(defrole lifespan-role
  :state {:start System.DateTime/Now
          :lifespan 0}
  (update [obj k]
          (let [{:keys [start lifespan]} (state obj k)]
            (when (< lifespan (.TotalMilliseconds (.Subtract System.DateTime/Now start)))
              (destroy obj)))))

(defrole bullet-movement-role
  (fixed-update [bullet k]
                (with-cmpt bullet [rb Rigidbody2D]
                  (move-forward rb 0.2))))


(def bullet-roles
  {::movement bullet-movement-role
   ::lifespan lifespan-role
   ::collision bullet-collision})

(defn shoot-bullet [start bearing parent]
  (let [bullet (GameObject/Instantiate
                (Resources/Load "missile" GameObject))]
    (with-cmpt bullet [rb Rigidbody2D,
                       tr Transform]
      (child+ parent bullet)
      (set! (.position tr) (v3 (.x start) (.y start) 1))
      (.MoveRotation rb bearing)
      (roles+ bullet
              (-> bullet-roles
                  (assoc-in [::lifespan :state :start] System.DateTime/Now)
                  (assoc-in [::lifespan :state :lifespan] 2000)))
      bullet)))

(defn shoot [obj layer parent]
  (with-cmpt obj [rb Rigidbody2D]
    (let [bullet (shoot-bullet (.position rb) (.rotation rb) parent)]
      (set! (.layer bullet) layer)
      bullet)))

(defrole player-shooting-role
  (update [obj k]
          (with-cmpt obj [rb Rigidbody2D]
            (when (Input/GetKeyDown "space")
              (shoot obj player-bullets-layer (parent obj))))))

(def player-roles
  {::movement player-movement-role
   ::shooting player-shooting-role
   ::health (update health-role :state assoc :health 10)})

(defrole enemy-shooting-role
  :state {:last-shot System.DateTime/Now}
  (update [obj k]
          (let [{:keys [target last-shot]} (state obj k)
                now System.DateTime/Now]
            (when (and (obj-nil target)
                       (< 1000 (.TotalMilliseconds (.Subtract now last-shot))))
              (update-state obj k assoc :last-shot now)
              (shoot obj enemy-bullets-layer (parent obj))))))

(defrole enemy-movement-role
  :state {:target nil}
  (fixed-update [obj k]
                (when-let [target (obj-nil (:target (state obj k)))]
                  (a/let [(a/with-cmpt rb1 Rigidbody2D) obj
                          (a/o pos1 position, rot1 rotation) rb1
                          (a/with-cmpt (a/o pos2 position) Rigidbody2D) target
                          pos-diff (v2- pos2 pos1)
                          rot-diff (Vector2/SignedAngle
                                    (bearing-vector rot1)
                                    pos-diff)]
                    (.MoveRotation rb1
                                   (+ rot1 (Mathf/Clamp -1 rot-diff 1)))))))

(def enemy-roles
  {::shooting enemy-shooting-role
   ::movement enemy-movement-role
   ::health (update health-role :state assoc :health 10)})

(defn make-enemy [protagonist parent]
  (let [enemy (GameObject/Instantiate (Resources/Load "villain" GameObject))]
    (child+ parent enemy)
    (roles+ enemy
            (-> enemy-roles
                (assoc-in [::movement :state :target] protagonist)
                (assoc-in [::shooting :state :target] protagonist)))))

(defn setup []
;; Game object to hold all generated objects
  (let [holder (object-named "Generated")]
       (doseq [child (children holder)]
         (destroy child))
       ;; Load the "fighter" prefab into the scene graph
       (let [player (GameObject/Instantiate (Resources/Load "fighter"))]
         (child+ holder player)
         ;; Set its name
         (set! (.name player) "player")
         (roles+ player player-roles)
         (make-enemy player holder))))

from fighter-tutorial.

sogaiu avatar sogaiu commented on June 1, 2024

@saikyun Thanks for this, with your work-around and working example, was able to get through the tutorial with 2018.1.0f2.

from fighter-tutorial.

saikyun avatar saikyun commented on June 1, 2024

@sogaiu Cool! I'm happy to hear that. :)

from fighter-tutorial.

sogaiu avatar sogaiu commented on June 1, 2024

Commenting out:

(scn/register bullet ::bullet)

seems to be another work-around.

I think the current situation may have something to do with:

  • arcadia.scene maintains label-registry for lookup of objects to labels and labels to objects
  • label-registry is affected via arcadia.scene/{register,retire} which are both used in the tutorial
  • there are 3 calls to arcadia.core/retire (which is distinct from arcadia.scene/retire)
  • arcadia.core/retire calls Destroy but doesn't affect arcadia.scene's label-registry

I got the impression that the label-registry gets out of sync with which bullet objects still exist -- arcadia.scene/register is used to track them, but arcadia.core/retire is used to directly get rid of them, so this leaves the label-registry referring to no longer valid bullet objects.

Or something like that :)

from fighter-tutorial.

Related Issues (11)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.