public AudioSystem(int maxSoundEffects, Map map = null, RayCaster rayCaster = null) { Map = map; RayCaster = rayCaster; Sounds = new List <SoundBuffer>(); MaxSoundEffects = maxSoundEffects; inPlaySounds = new Sound[MaxSoundEffects]; }
private bool CanSeeTarget(Entity target) { var vector = target.Location - Location; var maxDistance = (int)Math.Min(vector.Length, 500); var result = RayCaster.CastRay(Services.Game.Level, Location, vector, CollisionCheckType.BlocksProjectiles, maxDistance); return(!result.Hit); }
public Renderer(RayCaster rayCaster, RenderWindow renderWindow, RenderTexture drawBuffer, Map map, float fov, Color ambientLight) { //Assign local variables Caster = rayCaster; Screen = renderWindow; Buffer = drawBuffer; Map = map; Fov = fov; AmbientLight = ambientLight; //Calculate inital values for some variables HalfFov = fov / 2; DistanceToProjectionPlane = (Buffer.Size.X / 2f) / TanD(HalfFov); Textures = new List <Texture>(); DepthPerStrip = new float[Buffer.Size.X]; AtlasTileSize = new Vector2f(Caster.CellSize, Caster.CellSize); Angles = new float[Buffer.Size.X]; LightMultiplier = 4000; for (int x = 0; x < Buffer.Size.X; x++) { Angles[x] = AtanD((x - Buffer.Size.X / 2.0f) / DistanceToProjectionPlane); } FloorVertices = new Vertex[Buffer.Size.X * Buffer.Size.Y]; WallVertices = new Vertex[Buffer.Size.X * 2]; float aspectRatio = Buffer.Size.X / (float)Buffer.Size.Y; DisplayVertices = new Vertex[] { new Vertex { Position = new Vector2f(Screen.Size.X / 2 - (Screen.Size.Y * aspectRatio) / 2, 0), TexCoords = new Vector2f(0, Buffer.Size.Y - 1), Color = Color.White }, new Vertex { Position = new Vector2f(Screen.Size.X / 2 - (Screen.Size.Y * aspectRatio) / 2, Screen.Size.Y - 1), TexCoords = new Vector2f(0, 0), Color = Color.White }, new Vertex { Position = new Vector2f(Screen.Size.X / 2 + (Screen.Size.Y * aspectRatio) / 2, Screen.Size.Y - 1), TexCoords = new Vector2f(Buffer.Size.X - 1, 0), Color = Color.White }, new Vertex { Position = new Vector2f(Screen.Size.X / 2 + (Screen.Size.Y * aspectRatio) / 2, 0), TexCoords = new Vector2f(Buffer.Size.X - 1, Buffer.Size.Y - 1), Color = Color.White }, }; }
public Tuple <IInteractable, RaycastHit> GetInteractableFromRay(Ray ray, float range) { if (!RayCaster.CastRay(ray, range, out RaycastHit hit)) { return(null); } var interactable = hit.transform.GetComponent <IInteractable>(); return(interactable == null ? null : new Tuple <IInteractable, RaycastHit>(interactable, hit)); }
public Tuple <IInteractable, RaycastHit> GetInteractableFromRay(Ray ray, float range) { _distanceToClosestTarget = range; SetAllInteractables(); foreach (Transform t in _interactables) { // Don't hit yourself :| if (t == _self) { continue; } Vector3 rayVector = ray.direction; Vector3 rayToTargetVector = t.position - ray.origin; float distance = rayToTargetVector.magnitude; if (_distanceToClosestTarget <= distance) { continue; } float lookPercentage = Vector3.Dot(rayVector.normalized, rayToTargetVector.normalized); if (lookPercentage < Threshold) { continue; } // if (lookPercentage < _bestLookPercentage) return; _closestTarget = t; _distanceToClosestTarget = rayToTargetVector.magnitude; } if (_closestTarget == null) { return(null); } // TODO: Implement a "Closest point" method; Basically, if you're aiming slightly above the head, then the point should be the top of the head. // If you're aiming slightly top-left, then the point should be the upper-left-most area of the object etc.. // Currently it simply rays to the middle of the object. RayCaster.LineCast(ray.origin, _closestTarget.position, out RaycastHit hit); var result = new Tuple <IInteractable, RaycastHit>(_closestTarget.GetComponent <IInteractable>(), hit); _closestTarget = null; return(result); }
private void Awake() { if (instance == null || instance == this) { instance = this; Initialise(); } else { Destroy(this); } }
// Use this for initialization void Start () { //Obtain agent controller controller = GetComponent<Controller>(); //Obtain agent sensors foreach(RayCaster ray in GetComponents<RayCaster>()) { if (ray.id.Equals("FRONT")) front = ray; else if (ray.id.Equals("LEFT")) left = ray; else if (ray.id.Equals("RIGHT")) right = ray; } }
public void Update(GameTime gameTime) { if (InputManager.IsKeyPressed(Keys.F4)) { ScreenManager.PopScreen(); } MouseState currentState = Mouse.GetState(); if (currentState != previousState) { float deltaX = currentState.X - previousState.X; angle += deltaX * 20.0f * (float)gameTime.ElapsedGameTime.TotalSeconds; } Viewport viewport = ScreenManager.GraphicsDevice.Viewport; Mouse.SetPosition(viewport.Width / 2, viewport.Height / 2); Vector2 forward = new Vector2((float)Math.Cos(angle * Math.PI / 180), (float)Math.Sin(angle * Math.PI / 180)); Vector2 right = new Vector2(-forward.Y, forward.X); Vector2 movementDirection = forward * InputManager.VerticalAxis + right * InputManager.HorizontalAxis; if (movementDirection != Vector2.Zero) { movementDirection.Normalize(); Vector2 velocity = movementDirection * movementSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds; // do collision detection RayCaster.HitData hitData; float dirAngle = (float)Math.Atan2(velocity.Y, velocity.X); if (RayCaster.RayIntersectsGrid(position, dirAngle, 32, out hitData, currentMap.GetIsTileOccupiedFunction("walls1"), 16)) { if (hitData.rayLength >= 0) { float vel = velocity.Length(); velocity.Normalize(); } } player.position = position; velocity = currentMap.Move(velocity, player); position += velocity; } }
protected override int CreateMarker(float xPos, int rowIndex, Transform newColumn, int columnIndex) { float zPos = MarkerSizeAdjustedZStartPos - (distanceBetweenCreatedMarkers * rowIndex); var markerPos = new Vector3(xPos, creationHeightAboveFloor, zPos); Vector3 checkPos = markerPos; checkPos.y += grid.minimumOpenAreaAroundMarkers.y / 2; if (RayCaster.CheckBox(checkPos, grid.minimumOpenAreaAroundMarkers * 0.5f, Quaternion.identity)) { return(0); } InstantiateMarker("Column " + rowIndex, markerPos, newColumn); return(1); }
/// <summary> /// Returns false if the object was found to be inside another object (and was therefore moved from inside this method) /// </summary> private bool GetCollisions(ref Vector3 currPos, ref Vector3 currSize, out bool collForward, out bool collLeft, out bool collBack, out bool collRight) { collForward = false; collLeft = false; collBack = false; collRight = false; Collider[] colliders = RayCaster.OverLapBox(currPos, currSize, Quaternion.identity); int collidersSize = colliders.Length; if (collidersSize == 0) { currSize.x += boxCheckDistanceIncreasePerAttempt; currSize.z += boxCheckDistanceIncreasePerAttempt; } var collNames = ""; foreach (Collider coll in colliders) { bool isNotInsideOtherObject = CheckCollidingDirections(ref currPos, coll, ref collForward, ref collLeft, ref collBack, ref collRight, false, true); if (!isNotInsideOtherObject) { DoSubCollisionChecking(ref currPos, ref currSize, collidersSize); return(false); } if (collNames != "") { collNames += ","; } collNames += " " + coll.name; } Logging.Log($"Collided with {collNames}"); return(true); }
// Use this for initialization void Start() { // rCaster = GameObject.FindGameObjectWithTag("EditorOnly").GetComponent<RayCastF>(); rCaster = Camera.main.GetComponent <RayCaster>(); //if the upleftpos target is at 0.0.0 we put back the targets at the last calibration if (FovStatic.upLeftPos != new Vector3(0, 0, 0)) { ResumeLastCalibration(); } //logs name and scenetimer LoggerBehavior.sceneName = "Fov calibration"; LoggerBehavior.sceneTimer = 0; //change text on the targets RandomizeText(); //disable targets UpRight.SetActive(false); DownRight.SetActive(false); DownLeft.SetActive(false); }
void SetupEngines() { // "The core of Svelto.ECS" ??? m_EnginesRoot = new EnginesRoot(new UnitySumbmissionEntityViewScheduler()); // Factory for creating all entities (?) m_EntityFactory = m_EnginesRoot.GenerateEntityFactory(); // ??? IEntityFunctions entityFunctions = m_EnginesRoot.GenerateEntityFunctions(); // Factory used to create Unity GameObjects (wrapper around GameObject.Instantiate) GameObjectFactory gameObjectFactory = new GameObjectFactory(); IRayCaster rayCaster = new RayCaster(); ITime time = new FrameTimer(); PlayerInputEngine playerInputEngine = new PlayerInputEngine(); AimingEngine aimingEngine = new AimingEngine(); GunShootingEngine gunShootingEngine = new GunShootingEngine(rayCaster); GunEffectsEngine gunEffectsEngine = new GunEffectsEngine(gameObjectFactory); ZombieSpawnerEngine zombieSpawnerEngine = new ZombieSpawnerEngine(gameObjectFactory, m_EntityFactory); ZombieMovementEngine zombieMovementEngine = new ZombieMovementEngine(time); ZombieAnimationEngine zombieAnimationEngine = new ZombieAnimationEngine(); HUDEngine hudEngine = new HUDEngine(); DeathEngine deathEngine = new DeathEngine(entityFunctions); m_EnginesRoot.AddEngine(playerInputEngine); m_EnginesRoot.AddEngine(aimingEngine); m_EnginesRoot.AddEngine(gunShootingEngine); m_EnginesRoot.AddEngine(gunEffectsEngine); m_EnginesRoot.AddEngine(zombieSpawnerEngine); m_EnginesRoot.AddEngine(zombieMovementEngine); m_EnginesRoot.AddEngine(zombieAnimationEngine); m_EnginesRoot.AddEngine(hudEngine); m_EnginesRoot.AddEngine(deathEngine); }
public void StartSFMLProgram() { #region Initialization Map Map = new Map(_m.GetLength(0), _m.GetLength(1)); for (int y = 0; y < _m.GetLength(1); y++) { for (int x = 0; x < _m.GetLength(0); x++) { switch (_m[y, x]) { case 1: Map[x, y] = new Tile { Solid = true, DownAtlas = new Vector2i(1, 0), UpAtlas = new Vector2i(1, 0), LeftAtlas = new Vector2i(1, 0), RightAtlas = new Vector2i(1, 0) }; break; case 2: Map[x, y] = new CircleTile { Solid = true, DownAtlas = new Vector2i(1, 0), UpAtlas = new Vector2i(1, 0), LeftAtlas = new Vector2i(1, 0), RightAtlas = new Vector2i(1, 0), CeilAtlas = new Vector2i(0, 0), FloorAtlas = new Vector2i(2, 0), //IsCeilMap = true }; break; case 5: Map[x, y] = new Tile { Solid = false, DownAtlas = new Vector2i(0, 0), UpAtlas = new Vector2i(0, 0), LeftAtlas = new Vector2i(1, 0), RightAtlas = new Vector2i(1, 0), CeilAtlas = new Vector2i(0, 0), FloorAtlas = new Vector2i(5, 0) }; break; case 0: Map[x, y] = new Tile { Solid = false, DownAtlas = new Vector2i(0, 0), UpAtlas = new Vector2i(0, 0), LeftAtlas = new Vector2i(1, 0), RightAtlas = new Vector2i(1, 0), CeilAtlas = new Vector2i(0, 0), FloorAtlas = new Vector2i(5, 0) }; break; case 6: Map[x, y] = new Tile { Solid = false, DownAtlas = new Vector2i(0, 0), UpAtlas = new Vector2i(0, 0), LeftAtlas = new Vector2i(1, 0), RightAtlas = new Vector2i(1, 0), CeilAtlas = new Vector2i(0, 0), FloorAtlas = new Vector2i(5, 0), IsCeilMap = true }; break; } } } window = new RenderWindow(new VideoMode(800, 600), "SFML window", Styles.Default); window.SetVisible(true); window.Closed += new EventHandler(OnClosed); window.KeyPressed += new EventHandler <KeyEventArgs>(OnKeyPressed); window.MouseMoved += Window_MouseMoved; //Vector2f screen = new Vector2f(200, 100); Vector2f screen = new Vector2f(window.Size.X, window.Size.Y); screen *= 0.3f; rs = new RenderTexture((uint)screen.X, (uint)screen.Y); caster = new RayCaster(Map, 32); Renderer ren = new Renderer(caster, window, rs, Map, fov, new Color(16, 16, 16)); ren.Textures.Add(new Texture("Texture.png")); ren.MapAtlasInUse = 0; #endregion Vector2f player = new Vector2f(caster.CellSize * 6 + 8, caster.CellSize * 5 + 8); Vector2f sp1 = player + new Vector2f(70, 15); Vector2f sp2 = player + new Vector2f(50, 70); Vector2f sp3 = new Vector2f(caster.CellSize * 6 + 8, caster.CellSize * 5 + 8) + new Vector2f(30, -30); Vector2f scen = sp1 + new Vector2f(60, 60); Vector2f M; font = new Font("Perfect DOS VGA 437 Win.ttf"); Text t = new Text("Fps: ", font, 16); int fps = 0; int fpsCounter = 0; int ticks = Environment.TickCount; int ticksFps = Environment.TickCount; int timeDelta = 0; var lamps = new List <Light>(); //{ // new Light ( // new Vector2f(sp1.X,sp1.Y), // new Color(255,255,255) // ), // new Light ( // new Vector2f(sp2.X,sp2.Y), // new Color(128,128,0) // ) //}; List <Sprite> sprites = new List <Sprite>(); Random r = new Random(); for (int i = 0; i < 5; i++) { sprites.Add(new Sprite ( new Vector2f((float)r.NextDouble() * caster.CellSize * Map.Tiles.GetLength(0), (float)r.NextDouble() * caster.CellSize * Map.Tiles.GetLength(1)), new Vector2i(3, 0) )); } Random rand = new Random(); lamps = sprites.Select(s => new Light(s.Position, new Color((byte)(rand.NextDouble() * 80), 0, (byte)(rand.NextDouble() * 80)))).ToList(); ren.GenerateLightMap(lamps, 0.5f); //sprites.Add(new Sprite //( // sp2, // new Vector2i(3, 0) //)); //Sprite p = new Sprite //( // sp1, // new Vector2i(3, 0) //); //sprites.Add(p); AudioSystem audio = new AudioSystem(32, Map, caster); Sprite playerSprite = new Sprite(player, new Vector2i(0, 0)); audio.Listener = playerSprite; int a = audio.LoadSound("ts.wav"); audio.PlaySound(a, true, sp1); float look = rs.Size.Y / 2; float height = caster.CellSize / 2; ren.SkyPosition = new Vector2f(5, 5); ren.SkyAtlas = new Vector2i(6, 0); window.MouseWheelScrolled += (o, e) => { height += e.Delta / 1; if (height > caster.CellSize) { height = caster.CellSize; } if (height < 0) { height = 0; } }; while (window.IsOpen) { if (Environment.TickCount - ticksFps >= timeDelta) { ticksFps = Environment.TickCount; if (Environment.TickCount - ticks >= 1000) { fps = fpsCounter; fpsCounter = 0; ticks = Environment.TickCount; } angle -= (window.Size.X / 2 - Mouse.GetPosition(window).X) / 4f; look += (window.Size.Y / 2 - Mouse.GetPosition(window).Y) / 3f; if (look < 0) { look = 0; } if (look > rs.Size.Y) { look = rs.Size.Y; } ren.SkyPosition += new Vector2f(0.01f, 0.05f); if (Keyboard.IsKeyPressed(Keyboard.Key.P)) { lamps.Add( new Light(player, new Color(255, 255, 255))); } angle -= Keyboard.IsKeyPressed(Keyboard.Key.Left) ? 2 : 0; angle += Keyboard.IsKeyPressed(Keyboard.Key.Right) ? 2 : 0; M = new Vector2f(0, 0); if (Keyboard.IsKeyPressed(Keyboard.Key.W)) { M += new Vector2f(CosD(angle) * 2, SinD(angle) * 2); } if (Keyboard.IsKeyPressed(Keyboard.Key.S)) { M -= new Vector2f(CosD(angle) * 2, SinD(angle) * 2); } if (Keyboard.IsKeyPressed(Keyboard.Key.D)) { M += new Vector2f(CosD(angle + 90) * 2, SinD(angle + 90) * 2); } if (Keyboard.IsKeyPressed(Keyboard.Key.A)) { M += new Vector2f(CosD(angle - 90) * 2, SinD(angle - 90) * 2); } RayResult R = caster.RayCast(player, 0); if (R.Magnitude < Math.Abs(M.X) + 10 && Math.Sign(M.X) == 1) { M.X = 0; } R = caster.RayCast(player, 180); if (R.Magnitude < Math.Abs(M.X) + 10 && Math.Sign(M.X) == -1) { M.X = 0; } R = caster.RayCast(player, 90); if (R.Magnitude < Math.Abs(M.Y) + 10 && Math.Sign(M.Y) == 1) { M.Y = 0; } R = caster.RayCast(player, 270); if (R.Magnitude < Math.Abs(M.Y) + 10 && Math.Sign(M.Y) == -1) { M.Y = 0; } player += M; Mouse.SetPosition(new Vector2i((int)window.Size.X / 2, (int)window.Size.Y / 2), window); window.DispatchEvents(); rs.Clear(Color.Black); playerSprite.Position = player; playerSprite.Angle = angle; audio.UpdateAudio(); ren.Render(player, angle, height, look, sprites, lamps); t.DisplayedString = $"Fps: {fps} - Lights: {lamps.Count}"; rs.Draw(t); ren.ShowBuffer(); Thread.Sleep(0); fpsCounter++; } } }
private static bool CheckIfCollidingVertical(Vector3 pos, float dist) { var ray = new Ray(pos, dist > 0 ? Vector3.up : Vector3.down); return(RayCaster.CastRay(ray, Mathf.Abs(dist))); }
// Use this for initialization void Start() { displaySelection = 0; CamCaster = GetComponent <RayCaster>(); }
/// <summary> /// Before to start a review of Svelto.ECS terminologies: /// - Entity: /// it must be a real and concrete entity that you can explain /// in terms of game design. The name of each entity should reflect /// a specific concept from the game design domain /// - Engines (Systems): /// Where all the logic lies. Engines operates on EntityViews or EntityStructs /// - EntityViews and EntitiyViewStructs: /// EntityViews maps Entity Components. The Engines can't /// access directly to each entity (as a single set of components), but /// through component sets defined by the EntityView. /// They act as component filters and expose only the entity components /// that the Engine is interested in. /// EntityViews are actually defined with the Engine so they /// come together with the engine and in the same namespace of the engine. /// EntityViewStructs should always be used, while EntityViews as /// class use should be considered an exception. /// - Component Interfaces: /// Components must be seen as data holders. There may be implementation /// exceptions, but the interface must declare a group /// of readable and/or writeable data. /// In Svelto.ECS components are always interfaces declaring /// Setters and Getters of Value Types. DispatchOnSet /// and DispatchOnChange must not be seen as events, but /// as pushing of data instead of data polling, similar /// to the concept of DataBinding. /// - Implementors: /// Being components interfaces, they must be implemented through /// Implementors. The relation Implementors to Components /// is not 1:1 so that you can group several /// components into fewer implementors. This allows to easily /// share data between components. Implementors also act /// as bridge between the platform and Svelto.ECS. /// Since Components can hold only value types, Implementors /// are the objects that can interact directly with the platform /// objects, I.E.: RigidBody, Transform and so on. /// Note: IComponents must hold only valuetypes for /// code design purposes and not optmization purposes. /// The reason is that all the logic must lie in the engines /// so Components cannot hold references to instances that can /// expose functions with logic. /// - EntityStructs: /// In order to write Data Oriented Cache Friendly and allocation 0 code, Svelto.ECS /// also supports EntityStructs. /// - EntityDescriptors: /// Gives a way to formalize your Entity in svelto.ECS, it also /// defoines the EntityViews, EntityStructs and EntityViewStructs that must be generated once the /// Entity is built /// </summary> void SetupEngines() { //The Engines Root is the core of Svelto.ECS. You must NEVER inject the EngineRoot //as it is, therefore the composition root must hold a reference or it will be //GCed. //the UnitySumbmissionEntityViewScheduler is the scheduler that is used by the EnginesRoot to know //when to inject the EntityViews. You shouldn't use a custom one unless you know what you //are doing or you are not working with Unity. _enginesRoot = new EnginesRoot(new UnityEntitySubmissionScheduler()); //Engines root can never be held by anything else than the context itself to avoid leaks //That's why the EntityFactory and EntityFunctions are generated. //The EntityFactory can be injected inside factories (or engine acting as factories) //to build new entities dynamically _entityFactory = _enginesRoot.GenerateEntityFactory(); //The entity functions is a set of utility operations on Entities, including //removing an entity. I couldn't find a better name so far. var entityFunctions = _enginesRoot.GenerateEntityFunctions(); //the ISequencer is one of the 2 official ways available in Svelto.ECS //to communicate. They are mainly used for two specific cases: //1) specify a strict execution order between engines (engine logic //is executed horizontally instead than vertically, I will talk about this //in my articles). 2) filter a data token passed as parameter through //engines. The ISequencer is also not the common way to communicate //between engines PlayerDeathSequencer playerDeathSequence = new PlayerDeathSequencer(); EnemyDeathSequencer enemyDeathSequence = new EnemyDeathSequencer(); //wrap non testable unity static classes, so that //can be mocked if needed. IRayCaster rayCaster = new RayCaster(); ITime time = new Time(); //Player related engines. ALL the dependencies must be solved at this point //through constructor injection. var playerShootingEngine = new PlayerGunShootingEngine(rayCaster, time); var playerMovementEngine = new PlayerMovementEngine(rayCaster, time); var playerAnimationEngine = new PlayerAnimationEngine(); var playerDeathEngine = new PlayerDeathEngine(playerDeathSequence, entityFunctions); //Enemy related engines var enemyAnimationEngine = new EnemyAnimationEngine(time, enemyDeathSequence, entityFunctions); var enemyAttackEngine = new EnemyAttackEngine(time); var enemyMovementEngine = new EnemyMovementEngine(); //GameObjectFactory allows to create GameObjects without using the Static //method GameObject.Instantiate. While it seems a complication //it's important to keep the engines testable and not //coupled with hard dependencies references (read my articles to understand //how dependency injection works and why solving dependencies //with static classes and singletons is a terrible mistake) GameObjectFactory factory = new GameObjectFactory(); //Factory is one of the few patterns that work very well with ECS. Its use is highly encouraged IEnemyFactory enemyFactory = new EnemyFactory(factory, _entityFactory); var enemySpawnerEngine = new EnemySpawnerEngine(enemyFactory, entityFunctions); var enemyDeathEngine = new EnemyDeathEngine(entityFunctions, enemyDeathSequence); //hud and sound engines var hudEngine = new HUDEngine(time); var damageSoundEngine = new DamageSoundEngine(); var scoreEngine = new ScoreEngine(); //The ISequencer implementation is very simple, but allows to perform //complex concatenation including loops and conditional branching. //These two sequencers are a real stretch and are shown only for explanatory purposes. //Please do not see sequencers as a way to dispatch or broadcast events, they are meant only and exclusively //to guarantee the order of execution of the involved engines. //For this reason the use of sequencers is and must be actually rare, as perfectly encapsulated engines //do not need to be executed in specific order. //a Sequencer can: //- ensure the order of execution through one step only (one step executes in order several engines) //- ensure the order of execution through several steps. Each engine inside each step has the responsibility //to trigger the next step through the use of the Next() function //- create paths with branches and loop using the Condition parameter. playerDeathSequence.SetSequence( new Steps //sequence of steps, this is a dictionary! { { /*from: */ playerDeathEngine, //when the player dies /*to: */ new To <PlayerDeathCondition> //all these engines in the list will be called in order (which in this //case was not important at all, so stretched!!) { { PlayerDeathCondition.Death, playerMovementEngine, playerAnimationEngine, enemyAnimationEngine, damageSoundEngine, hudEngine } } } } ); enemyDeathSequence.SetSequence( new Steps { { //first step enemyDeathEngine, new To <EnemyDeathCondition> { //TIP: use GO To Type Declaration to go directly to the Class code of the //engine instance { EnemyDeathCondition.Death, scoreEngine, enemyAnimationEngine } } }, { //second step enemyAnimationEngine, //after the death animation is actually finished new To <EnemyDeathCondition> { { EnemyDeathCondition.Death, enemySpawnerEngine } //call the spawner engine } } } ); //All the logic of the game must lie inside engines //Player engines _enginesRoot.AddEngine(playerMovementEngine); _enginesRoot.AddEngine(playerAnimationEngine); _enginesRoot.AddEngine(playerShootingEngine); _enginesRoot.AddEngine(new PlayerInputEngine()); _enginesRoot.AddEngine(new PlayerGunShootingFXsEngine()); _enginesRoot.AddEngine(playerDeathEngine); //enemy engines _enginesRoot.AddEngine(enemySpawnerEngine); _enginesRoot.AddEngine(enemyAttackEngine); _enginesRoot.AddEngine(enemyMovementEngine); _enginesRoot.AddEngine(enemyAnimationEngine); _enginesRoot.AddEngine(enemyDeathEngine); //other engines _enginesRoot.AddEngine(new ApplyingDamageToTargetsEngine()); _enginesRoot.AddEngine(new CameraFollowTargetEngine(time)); _enginesRoot.AddEngine(new CharactersDeathEngine()); _enginesRoot.AddEngine(damageSoundEngine); _enginesRoot.AddEngine(hudEngine); _enginesRoot.AddEngine(scoreEngine); }
void Start() { gc = GetComponent <GameController>(); rc = GetComponent <RayCaster>(); }
private static bool CheckIfCollidingOnZ(Vector3 pos, float dist) { var ray = new Ray(pos, dist > 0 ? Vector3.forward : Vector3.back); return(RayCaster.CastRay(ray, Mathf.Abs(dist))); }
void Start() { // rCaster = GameObject.FindGameObjectWithTag("EditorOnly").GetComponent<RayCastF>(); rCaster = Camera.main.GetComponent <RayCaster>(); }
/// <summary> /// Before to start, let's review some of the Svelto.ECS terms: /// - Entity: /// it must be a real and concrete entity that you can explain in terms of game design. The name of each /// entity should reflect a specific concept from the game design domain /// - Engines (Systems): /// Where all the logic lies. Engines operates on EntityViewStructs and EntityStructs /// - EntityStructs: /// EntityStructs is the preferred way to store entity data. They are just plain structs of pure data (no /// objects) /// - EntityViewStructs: /// EntityViewStructs are used to wrap Objects that come from OOP libraries. You will never use it unless /// you are forced to mix your ECS code with OOP code because of external libraries or platforms. /// The Objects are known to svelto through Component Interfaces. /// - Component Interfaces: /// Components must be seen as data holders. In Svelto.ECS components are always interfaces declaring /// Setters and Getters of Value Types coming from the Objects they wrap /// - Implementors: /// The components interfaces must be implemented through Implementors and the implementors are the /// Objects you need to wrap. /// - EntityDescriptors: /// Gives a way to formalise your Entity, it also defines the EntityStructs and EntityViewStructs that must /// be generated once the Entity is built /// </summary> void SetupEngines() { //The Engines Root is the core of Svelto.ECS. You shouldn't inject the EngineRoot, //therefore the composition root must hold a reference or it will be GCed. //the UnitySumbmissionEntityViewScheduler is the scheduler that is used by the EnginesRoot to know //when to submit the entities. Custom ones can be created for special cases. _unityEntitySubmissionScheduler = new UnityEntitySubmissionScheduler(); _enginesRoot = new EnginesRoot(_unityEntitySubmissionScheduler); //The EntityFactory can be injected inside factories (or engine acting as factories) to build new entities //dynamically _entityFactory = _enginesRoot.GenerateEntityFactory(); //The entity functions is a set of utility operations on Entities, including removing an entity. I couldn't //find a better name so far. var entityFunctions = _enginesRoot.GenerateEntityFunctions(); //Sequencers are the official way to guarantee order between engines, but may not be the best way for //your product. var playerDeathSequence = new PlayerDeathSequencer(); var enemyDeathSequence = new EnemyDeathSequencer(); //wrap non testable unity static classes, so that can be mocked if needed. IRayCaster rayCaster = new RayCaster(); ITime time = new Time(); //Player related engines. ALL the dependencies must be solved at this point through constructor injection. var playerShootingEngine = new PlayerGunShootingEngine(rayCaster, time); var playerMovementEngine = new PlayerMovementEngine(rayCaster, time); var playerAnimationEngine = new PlayerAnimationEngine(); var playerDeathEngine = new PlayerDeathEngine(playerDeathSequence, entityFunctions); //Enemy related engines var enemyAnimationEngine = new EnemyAnimationEngine(time, enemyDeathSequence, entityFunctions); var enemyAttackEngine = new EnemyAttackEngine(time); var enemyMovementEngine = new EnemyMovementEngine(); //GameObjectFactory allows to create GameObjects without using the Static method GameObject.Instantiate. //While it seems a complication it's important to keep the engines testable and not coupled with hard //dependencies var gameObjectFactory = new GameObjectFactory(); //Factory is one of the few patterns that work very well with ECS. Its use is highly encouraged var enemyFactory = new EnemyFactory(gameObjectFactory, _entityFactory); var enemySpawnerEngine = new EnemySpawnerEngine(enemyFactory, entityFunctions); var enemyDeathEngine = new EnemyDeathEngine(entityFunctions, enemyDeathSequence); //hud and sound engines var hudEngine = new HUDEngine(time); var damageSoundEngine = new DamageSoundEngine(); var scoreEngine = new ScoreEngine(); //The ISequencer implementation is very simple, but allows to perform //complex concatenation including loops and conditional branching. //These two sequencers are a real stretch and are shown only for explanatory purposes. //Please do not see sequencers as a way to dispatch or broadcast events, they are meant only and exclusively //to guarantee the order of execution of the involved engines. //For this reason the use of sequencers is and must be actually rare, as perfectly encapsulated engines //do not need to be executed in specific order. //a Sequencer can: //- ensure the order of execution through one step only (one step executes in order several engines) //- ensure the order of execution through several steps. Each engine inside each step has the responsibility //to trigger the next step through the use of the Next() function //- create paths with branches and loop using the Condition parameter. playerDeathSequence.SetSequence(playerDeathEngine, playerMovementEngine, playerAnimationEngine, enemyAnimationEngine, damageSoundEngine, hudEngine); enemyDeathSequence.SetSequence(enemyDeathEngine, scoreEngine, damageSoundEngine, enemyAnimationEngine, enemySpawnerEngine); //All the logic of the game must lie inside engines //Player engines _enginesRoot.AddEngine(playerMovementEngine); _enginesRoot.AddEngine(playerAnimationEngine); _enginesRoot.AddEngine(playerShootingEngine); _enginesRoot.AddEngine(new PlayerInputEngine()); _enginesRoot.AddEngine(new PlayerGunShootingFXsEngine()); _enginesRoot.AddEngine(playerDeathEngine); _enginesRoot.AddEngine(new PlayerSpawnerEngine(gameObjectFactory, _entityFactory)); //enemy engines _enginesRoot.AddEngine(enemySpawnerEngine); _enginesRoot.AddEngine(enemyAttackEngine); _enginesRoot.AddEngine(enemyMovementEngine); _enginesRoot.AddEngine(enemyAnimationEngine); _enginesRoot.AddEngine(enemyDeathEngine); //other engines _enginesRoot.AddEngine(new ApplyingDamageToTargetsEngine()); _enginesRoot.AddEngine(new CameraFollowTargetEngine(time)); _enginesRoot.AddEngine(new CharactersDeathEngine()); _enginesRoot.AddEngine(damageSoundEngine); _enginesRoot.AddEngine(hudEngine); _enginesRoot.AddEngine(scoreEngine); }
private void InitializeRayCaster() { _rayCaster = new RayCaster(PutPixel, (x, y, width, height) => { }); }
/// <summary> /// Before to start a review of Svelto.ECS terminologies: /// - Entity: /// it must be a real and concrete entity that you can explain /// in terms of game design. The name of each entity should reflect /// a specific concept from the game design domain /// - IComponents: /// Components must be seen as data holders. There are implementing /// exceptions, but logically it must be still see as a group /// of readable or writeable data. /// In Svelto.ECS components are always interfaces declaring /// Setters and Getters of ValueTypes. DispatchOnSet /// and DispatchOnChange must not be seen as events, but /// as pushing of data instead of data polling, similar /// to the concept of DataBinding. /// - Implementors: /// Being components interfaces, they must be implemented through /// Implementors. The relation Implementors to Components /// is not 1:1 so that you can, if logic, group several /// components in one implementor. This allows to easily /// share data between components. Implementors also act /// as bridge between the platform and Svelto.ECS. /// Since Components can hold only value types, Implementors /// are the objects that can interact directly with the platform /// objects, I.E.: RigidBody, Transform and so on. /// Note: IComponents must hold only valuetypes for /// code design purposes and not optmization purposes. /// The reason is that all the logic must lie in the engines /// so Components cannot hold references to instances that can /// expose functions with logic. /// - Engines: /// Where all the logic lies. Engines operates on EntityViews /// - EntityViews: /// EntityViews maps EntityComponents. The Engines can't /// access directly to each entity (as a single set of components), but /// through a component sets defined by EntityView. /// They act as a component filters and expose only the entity components /// that the Engine is interested in. /// EntityViews are actually defined by the need of the Engine so they /// come together with the engine and in the same namespace of the engine. /// - EntityStructs: /// In order to write Data Oriented Cache Friendly code, Svelto.ECS /// also support EntityStructs. Please check other examples to /// understand how to use them. However know that this kind of /// optimizations is very limited to special circumstances /// so the flexibility of EntityViews is most of the times what you need. /// - EntityDescriptors: /// Gives a way to formalize your Entity in svelto.ECS, it also /// groups the EntityViews that must be generated once the /// Entity is built /// </summary> void SetupEnginesAndEntities() { //The Engines Root is the core of Svelto.ECS. You must NEVER inject the EngineRoot //as it is, therefore the composition root must hold a reference or it will be //GCed. //the UnitySumbmissionEntityViewScheduler is the scheduler that is used by the EnginesRoot to know //when to inject the EntityViews. You shouldn't use a custom one unless you know what you //are doing or you are not working with Unity. _enginesRoot = new EnginesRoot(new UnitySumbmissionEntityViewScheduler()); //Engines root can never be held by anything else than the context itself to avoid leaks //That's why the EntityFactory and EntityFunctions are generated. //The EntityFactory can be injected inside factories (or engine acting as factories) //to build new entities dynamically _entityFactory = _enginesRoot.GenerateEntityFactory(); //The entity functions is a set of utility operations on Entities, including //removing an entity. I couldn't find a better name so far. var entityFunctions = _enginesRoot.GenerateEntityFunctions(); //GameObjectFactory allows to create GameObjects without using the Static //method GameObject.Instantiate. While it seems a complication //it's important to keep the engines testable and not //coupled with hard dependencies references (read my articles to understand //how dependency injection works and why solving dependencies //with static classes and singletons is a terrible mistake) GameObjectFactory factory = new GameObjectFactory(); //the ISequencer is one of the 3 official ways available in Svelto.ECS //to communicate. They are mainly used for two specific cases: //1) specify a strict execution order between engines (engine logic //is executed horizontally instead than vertically, I will talk about this //in my articles). 2) filter a data token passed as parameter through //engines. The ISequencer is also not the common way to communicate //between engines Sequencer playerDamageSequence = new Sequencer(); Sequencer enemyDamageSequence = new Sequencer(); //wrap non testable unity static classes, so that //can be mocked if needed. IRayCaster rayCaster = new RayCaster(); ITime time = new Time(); //Player related engines. ALL the dependecies must be solved at this point //through constructor injection. var playerHealthEngine = new HealthEngine(playerDamageSequence); var playerShootingEngine = new PlayerGunShootingEngine(enemyDamageSequence, rayCaster, time); var playerMovementEngine = new PlayerMovementEngine(rayCaster, time); var playerAnimationEngine = new PlayerAnimationEngine(); var playerDeathEngine = new PlayerDeathEngine(entityFunctions); //Enemy related engines var enemyAnimationEngine = new EnemyAnimationEngine(time); //HealthEngine is a different object for the enemy because it uses a different sequence var enemyHealthEngine = new HealthEngine(enemyDamageSequence); var enemyAttackEngine = new EnemyAttackEngine(playerDamageSequence, time); var enemyMovementEngine = new EnemyMovementEngine(); var enemySpawnerEngine = new EnemySpawnerEngine(factory, _entityFactory); var enemyDeathEngine = new EnemyDeathEngine(entityFunctions); //hud and sound engines var hudEngine = new HUDEngine(time); var damageSoundEngine = new DamageSoundEngine(); var scoreEngine = new ScoreEngine(); //The ISequencer implementaton is very simple, but allows to perform //complex concatenation including loops and conditional branching. playerDamageSequence.SetSequence( new Steps //sequence of steps, this is a dictionary! { { //first step enemyAttackEngine, //this step can be triggered only by this engine through the Next function new To //this step can lead only to one branch { //this is the only engine that will be called when enemyAttackEngine triggers Next() new IStep[] { playerHealthEngine } } }, { //second step playerHealthEngine, //this step can be triggered only by this engine through the Next function new To //once the playerHealthEngine calls step, all these engines will be called at once //depending by the condition a different set of engines will be triggered. The //order of the engines triggered is guaranteed. { //these engines will be called when the Next function is called with the DamageCondition.damage set { DamageCondition.Damage, new IStep[] { hudEngine, damageSoundEngine } }, //these engines will be called when the Next function is called with the DamageCondition.dead set { DamageCondition.Dead, new IStep[] { hudEngine, damageSoundEngine, playerMovementEngine, playerAnimationEngine, enemyAnimationEngine, playerDeathEngine } } } } } ); enemyDamageSequence.SetSequence( new Steps { { playerShootingEngine, new To { //in every case go to enemyHealthEngine new IStep[] { enemyHealthEngine } } }, { enemyHealthEngine, new To { { DamageCondition.Damage, new IStep[] { enemyAnimationEngine, damageSoundEngine } }, { DamageCondition.Dead, new IStep[] { scoreEngine, enemyMovementEngine, enemyAnimationEngine, enemySpawnerEngine, damageSoundEngine, enemyDeathEngine } }, } } } ); //Mandatory step to make engines work //Player engines _enginesRoot.AddEngine(playerMovementEngine); _enginesRoot.AddEngine(playerAnimationEngine); _enginesRoot.AddEngine(playerShootingEngine); _enginesRoot.AddEngine(playerHealthEngine); _enginesRoot.AddEngine(new PlayerInputEngine()); _enginesRoot.AddEngine(new PlayerGunShootingFXsEngine()); //enemy engines _enginesRoot.AddEngine(enemySpawnerEngine); _enginesRoot.AddEngine(enemyAttackEngine); _enginesRoot.AddEngine(enemyMovementEngine); _enginesRoot.AddEngine(enemyAnimationEngine); _enginesRoot.AddEngine(enemyHealthEngine); _enginesRoot.AddEngine(enemyDeathEngine); //other engines _enginesRoot.AddEngine(new CameraFollowTargetEngine(time)); _enginesRoot.AddEngine(damageSoundEngine); _enginesRoot.AddEngine(hudEngine); _enginesRoot.AddEngine(scoreEngine); }
private static bool CheckIfCollidingOnX(Vector3 pos, float dist) { var ray = new Ray(pos, dist > 0 ? Vector3.right : Vector3.left); return(RayCaster.CastRay(ray, Mathf.Abs(dist))); }
public override RayResult OnIntersection(RayResult original, Vector2f O, float angle, RayCaster caster) { int points = LineCircleIntersections(caster.CellSize * original.Tile.X + (caster.CellSize / 2), caster.CellSize * original.Tile.Y + (caster.CellSize / 2), caster.CellSize / 2, original.Position, original.Position + new Vector2f(300 * CosD(angle), 300 * SinD(angle)), out Vector2f p1, out Vector2f p2); switch (points) { case 0: original.Valid = false; return(original); case 1: return(new RayResult { Valid = true, Magnitude = Distance(O, p1), Side = Side.None, Position = p1, Tile = original.Tile }); case 2: Vector2f final = Distance(O, p1) <= Distance(O, p2) ? p1 : p2; return(new RayResult { Valid = true, Magnitude = Distance(O, final), Side = Side.None, Position = final, Tile = original.Tile }); } original.Valid = true; return(original); }
/// <summary> /// Before to start, let's review some of the Svelto.ECS terms: /// - Entity: /// it must be a real and concrete entity that you can explain in terms of game design. The name of each /// entity should reflect a specific concept from the game design domain /// - Engines (Systems): /// Where all the logic lies. Engines operates on Entity Components /// - IEntityComponent: /// It's an Entity Component which can be used with Pure ECS /// - IEntityViewComponent: /// structs implementing this are used to wrap Objects that come from OOP libraries. You will never use it unless /// you are forced to mix your ECS code with OOP code because of external libraries or platforms. These special /// "Hybrid" component can hold only interfaces /// - Implementors: /// The EntityViewComponent exposed interfaces must be implemented by Implementors that are actually the /// Objects you need to wrap. /// - EntityDescriptors: /// Gives a way to formalise your Entity, it also defines the components that must /// be generated once the Entity is built /// </summary> void CompositionRoot(UnityContext contextHolder) { //the UnitySumbmissionEntityViewScheduler is the scheduler that is used by the EnginesRoot to know //when to submit the entities. Custom ones can be created for special cases. var unityEntitySubmissionScheduler = new UnityEntitiesSubmissionScheduler("survival"); //The Engines Root is the core of Svelto.ECS. You shouldn't inject the EngineRoot, //therefore the composition root class must hold a reference or it will be garbage collected. _enginesRoot = new EnginesRoot(unityEntitySubmissionScheduler); //The EntityFactory can be injected inside factories (or engine acting as factories) to build new entities //dynamically var entityFactory = _enginesRoot.GenerateEntityFactory(); //The entity functions is a set of utility operations on Entities, including removing an entity. I couldn't //find a better name so far. var entityFunctions = _enginesRoot.GenerateEntityFunctions(); var entityStreamConsumerFactory = _enginesRoot.GenerateConsumerFactory(); //wrap non testable unity static classes, so that can be mocked if needed (or implementation can change in general, without changing the interface). IRayCaster rayCaster = new RayCaster(); ITime time = new Time(); //GameObjectFactory allows to create GameObjects without using the Static method GameObject.Instantiate. //While it seems a complication it's important to keep the engines testable and not coupled with hard //dependencies var gameObjectFactory = new GameObjectFactory(); //Player related engines. ALL the dependencies must be solved at this point through constructor injection. var playerShootingEngine = new PlayerGunShootingEngine(rayCaster, time); var playerMovementEngine = new PlayerMovementEngine(rayCaster); var playerAnimationEngine = new PlayerAnimationEngine(); var playerDeathEngine = new PlayerDeathEngine(entityFunctions, entityStreamConsumerFactory); var playerInputEngine = new PlayerInputEngine(); var playerGunShootingFXsEngine = new PlayerGunShootingFXsEngine(entityStreamConsumerFactory); //Spawner engines are factories engines that can build entities var playerSpawnerEngine = new PlayerSpawnerEngine(gameObjectFactory, entityFactory); var restartGameOnPlayerDeath = new RestartGameOnPlayerDeathEngine(); //Player engines _enginesRoot.AddEngine(playerMovementEngine); _enginesRoot.AddEngine(playerAnimationEngine); _enginesRoot.AddEngine(playerShootingEngine); _enginesRoot.AddEngine(playerInputEngine); _enginesRoot.AddEngine(playerGunShootingFXsEngine); _enginesRoot.AddEngine(playerDeathEngine); _enginesRoot.AddEngine(playerSpawnerEngine); _enginesRoot.AddEngine(restartGameOnPlayerDeath); //Factory is one of the few OOP patterns that work very well with ECS. Its use is highly encouraged var enemyFactory = new EnemyFactory(gameObjectFactory, entityFactory); //Enemy related engines var enemyAnimationEngine = new EnemyChangeAnimationOnPlayerDeath(); var enemyDamageFX = new EnemySpawnEffectOnDamage(entityStreamConsumerFactory); var enemyAttackEngine = new EnemyAttackEngine(time); var enemyMovementEngine = new EnemyMovementEngine(); //Spawner engines are factories engines that can build entities var enemySpawnerEngine = new EnemySpawnerEngine(enemyFactory, entityFunctions); var enemyDeathEngine = new EnemyDeathEngine(entityFunctions, entityStreamConsumerFactory, time , new WaitForSubmissionEnumerator( unityEntitySubmissionScheduler)); //enemy engines _enginesRoot.AddEngine(enemySpawnerEngine); _enginesRoot.AddEngine(enemyAttackEngine); _enginesRoot.AddEngine(enemyMovementEngine); _enginesRoot.AddEngine(enemyAnimationEngine); _enginesRoot.AddEngine(enemyDeathEngine); _enginesRoot.AddEngine(enemyDamageFX); //abstract engines var applyDamageEngine = new ApplyDamageToDamageableEntitiesEngine(entityStreamConsumerFactory); var cameraFollowTargetEngine = new CameraFollowingTargetEngine(time); var deathEngine = new DispatchKilledEntitiesEngine(); //abstract engines (don't need to know the entity type) _enginesRoot.AddEngine(applyDamageEngine); _enginesRoot.AddEngine(deathEngine); _enginesRoot.AddEngine(cameraFollowTargetEngine); //hud and sound engines var hudEngine = new HUDEngine(entityStreamConsumerFactory); var damageSoundEngine = new DamageSoundEngine(entityStreamConsumerFactory); var scoreEngine = new UpdateScoreEngine(entityStreamConsumerFactory); //other engines _enginesRoot.AddEngine(damageSoundEngine); _enginesRoot.AddEngine(hudEngine); _enginesRoot.AddEngine(scoreEngine); var unsortedEngines = new SurvivalUnsortedEnginesGroup(new FasterList <IStepEngine>( new IStepEngine[] { playerMovementEngine, playerInputEngine, playerGunShootingFXsEngine, playerSpawnerEngine, playerAnimationEngine, enemySpawnerEngine, enemyMovementEngine, cameraFollowTargetEngine, hudEngine, restartGameOnPlayerDeath } )); var unsortedDamageEngines = new DamageUnsortedEngines(new FasterList <IStepEngine>( new IStepEngine[] { applyDamageEngine, damageSoundEngine, deathEngine } )); //Svelto ECS doesn't provide a tick system, hence it doesn't provide a solution to solve the order of execution //However it provides some option if you want to use them like the SortedEnginesGroup. _enginesRoot.AddEngine(new TickEnginesGroup(new FasterList <IStepEngine>(new IStepEngine[] { unsortedEngines , playerShootingEngine , enemyDamageFX , enemyAttackEngine , unsortedDamageEngines , playerDeathEngine , enemyDeathEngine , scoreEngine }))); BuildGUIEntitiesFromScene(contextHolder, entityFactory); }
public override (Vector2f top, Vector2f bottom) CalculateTextureCoords(RayResult original, Vector2f O, float angle, RayCaster caster) { float tx = Atan2(caster.CellSize * original.Tile.Y + (caster.CellSize / 2) - original.Position.Y, caster.CellSize * original.Tile.X + (caster.CellSize / 2) - original.Position.X) + (float)Math.PI; tx = (float)((tx * caster.CellSize) / (Math.PI * 2)); tx *= 4; tx %= (float)(Math.PI * 2); Vector2f top = new Vector2f( DownAtlas.X * caster.CellSize + tx, DownAtlas.Y * caster.CellSize); Vector2f bottom = new Vector2f( top.X, top.Y + caster.CellSize); return(top, bottom); }
protected virtual void Awake() { objectCollider = GetComponent <BoxCollider2D>(); rayCaster = GetComponent <RayCaster>(); thisTransform = transform; }
//Public interface public virtual RayResult OnIntersection(RayResult original, Vector2f O, float angle, RayCaster caster) { original.Valid = true; return(original); }
public virtual (Vector2f top, Vector2f bottom) CalculateTextureCoords(RayResult original, Vector2f O, float angle, RayCaster caster) { Vector2f textureCordUp; Vector2f textureCordDown; switch (original.Side) { case Side.Down: textureCordUp = new Vector2f( DownAtlas.X * caster.CellSize + (original.Position.X % caster.CellSize), DownAtlas.Y * caster.CellSize); textureCordDown = new Vector2f( textureCordUp.X, textureCordUp.Y + caster.CellSize); break; case Side.Up: textureCordUp = new Vector2f( UpAtlas.X * caster.CellSize + (original.Position.X % caster.CellSize), UpAtlas.Y * caster.CellSize); textureCordDown = new Vector2f( textureCordUp.X, textureCordUp.Y + caster.CellSize); break; case Side.Left: textureCordUp = new Vector2f( LeftAtlas.X * caster.CellSize + (original.Position.Y % caster.CellSize), LeftAtlas.Y * caster.CellSize); textureCordDown = new Vector2f( textureCordUp.X, textureCordUp.Y + caster.CellSize); break; case Side.Right: textureCordUp = new Vector2f( RightAtlas.X * caster.CellSize + (original.Position.Y % caster.CellSize), RightAtlas.Y * caster.CellSize); textureCordDown = new Vector2f( textureCordUp.X, textureCordUp.Y + caster.CellSize); break; default: textureCordUp = new Vector2f( (original.Position.Y % caster.CellSize), RightAtlas.Y * caster.CellSize); textureCordDown = new Vector2f( textureCordUp.X, textureCordUp.Y + caster.CellSize - 1); break; } return(textureCordUp, textureCordDown); }
private Collider[] GetMarkersWithinArea(Vector3 point, Vector3 currSize) { Collider[] overlaps = RayCaster.OverLapBoxTriggersIncludeMarkers(point, currSize, Quaternion.identity, markerLayerMask); return(overlaps); }