Comments (5)
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.
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.
@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.
@sogaiu Cool! I'm happy to hear that. :)
from fighter-tutorial.
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
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fighter-tutorial.