private void CastSpell(Hands.handEnum hand) { ElementsPair elementPair; GameObject bulletPoint; if (hand == Hands.handEnum.left) { elementPair = spellController.LeftHandElementsPair; bulletPoint = LeftBulletPoint; nextSpellCooldownLeft = Time.time + 0.5f; } else if (hand == Hands.handEnum.right) { elementPair = spellController.RightHandElementsPair; bulletPoint = RightBulletPoint; nextSpellCooldownRight = Time.time + 0.5f; } else { Debug.Log("[CastingControl][CastSpell] Error: inappropriate hand is provided - " + hand); return; } if (elementPair.isNonePair()) { return; } Spells.spellEnum spellEnum = Spells.elementsPairToSpellEnum[elementPair]; Spells.SpellDetails spellDetail = spellEnumToSpellDetails[spellEnum]; bool shouldCreateBullet = spellController; // === setup done. shoot out bullet Vector3 pos = bulletPoint.transform.position; Vector3 rotation = new Vector3(0, 0, 0); prefabScript = spellDetail.spellObject.GetComponent <FireConstantBaseScript>(); if (prefabScript == null) { // temporary effect, like a fireball prefabScript = spellDetail.spellObject.GetComponent <FireBaseScript>(); if (spellDetail.spellObject.GetComponent <FireBaseScript>().IsProjectile) { // set the start point near the hand rotation = cam.transform.rotation.eulerAngles; } } else { // TODO: Not sure if this way of checking for spell type is good idea. Maybe it is better to add "isProjectile" variable to Spells, but w/e // set the start point in front of the player a ways, rotated the same way as the player RaycastHit hit; pos = bulletPoint.transform.position; rotation = cam.transform.rotation.eulerAngles; rotation.x = 0; // this sets the spell up virtically pos.y = 0.0f; Physics.Raycast(bulletPoint.transform.position, cam.transform.forward, out hit, 9000000f, laycastLayerMask); if (hit.collider == null) { shouldCreateBullet = false; } pos = hit.point; } if (shouldCreateBullet && spellController.hasEnoughResourceToCast(elementPair, spellDetail.firstElementCost, spellDetail.secondElementCost)) { var spellPrefab = GameObject.Instantiate(spellDetail.spellObject, pos, Quaternion.Euler(rotation)); Elements.elemEnum curSecondElement = elementPair.Second; // this is because "DecrementElement" may modify this spellController.DecrementElement(elementPair.First, spellDetail.firstElementCost); spellController.DecrementElement(curSecondElement, spellDetail.secondElementCost); } }