protected override void _StartAction(RPGCharacterController controller, SwitchWeaponContext context) { RPGCharacterWeaponController weaponController = controller.GetComponent <RPGCharacterWeaponController>(); if (weaponController == null) { EndAction(controller); return; } context.LowercaseStrings(); bool changeRight = false; bool sheathRight = false; bool unsheathRight = false; int fromRight = controller.rightWeapon; int toRight = context.rightWeapon; bool changeLeft = false; bool sheathLeft = false; bool unsheathLeft = false; int fromLeft = controller.leftWeapon; int toLeft = context.leftWeapon; bool dualWielding = AnimationData.Is1HandedWeapon(fromRight) && AnimationData.Is1HandedWeapon(fromLeft); bool dualUnsheath = context.side == "dual"; bool dualSheath = false; int toAnimatorWeapon = 0; // Filter which side is changing. switch (context.side) { case "none": case "right": changeRight = true; if (AnimationData.Is2HandedWeapon(toRight) && !AnimationData.IsNoWeapon(fromLeft)) { changeLeft = true; toLeft = (int)Weapon.Unarmed; dualSheath = dualWielding; } break; case "left": changeLeft = true; if (AnimationData.Is2HandedWeapon(fromRight)) { changeRight = true; toRight = (int)Weapon.Unarmed; } break; case "dual": changeLeft = true; changeRight = true; dualSheath = dualWielding; break; case "both": changeLeft = true; changeRight = true; break; } // Set sheath location. switch (context.sheathLocation) { case "back": controller.animator.SetInteger("SheathLocation", 0); break; case "hips": controller.animator.SetInteger("SheathLocation", 1); break; } // If relaxing, just use the Relax action. if (context.type == "relax") { controller.StartAction("Relax"); return; } // Force unarmed if sheathing weapons. if (context.type == "sheath") { if (context.side == "left" || context.side == "dual" || context.side == "both") { toLeft = (int)Weapon.Unarmed; } else { toLeft = fromLeft; } if (context.side == "none" || context.side == "right" || context.side == "dual" || context.side == "both") { toRight = (int)Weapon.Unarmed; } else { toRight = fromRight; } } // Sheath weapons first if our starting weapon is different from our desired weapon and we're // not starting from an unarmed position. if (context.type == "sheath" || context.type == "switch") { sheathLeft = changeLeft && fromLeft != toLeft && !AnimationData.IsNoWeapon(fromLeft); sheathRight = changeRight && fromRight != toRight && !AnimationData.IsNoWeapon(fromRight); toAnimatorWeapon = AnimationData.ConvertToAnimatorWeapon(toLeft, toRight); } // Unsheath a weapon if our starting weapon is different from our desired weapon and we're // not ending on an unarmed position. if (context.type == "unsheath" || context.type == "switch") { unsheathLeft = changeLeft && fromLeft != toLeft && !AnimationData.IsNoWeapon(toLeft); unsheathRight = changeRight && fromRight != toRight && !AnimationData.IsNoWeapon(toRight); // If you're switching from the relaxed state, you can "unsheath" your fists. if (controller.isRelaxed && (toLeft == (int)Weapon.Unarmed || toRight == (int)Weapon.Unarmed)) { fromLeft = (int)Weapon.Relax; fromRight = (int)Weapon.Relax; sheathLeft = false; sheathRight = false; unsheathLeft = false; unsheathRight = true; dualSheath = false; dualUnsheath = false; } } /// /// Actually make changes to the weapon controller. /// if (context.type == "instant") { if (changeLeft) { weaponController.InstantWeaponSwitch(toLeft); } if (changeRight) { weaponController.InstantWeaponSwitch(toRight); } } else { // Sheath weapons first if that's necessary. if (dualSheath && (sheathRight || sheathLeft)) { // Dual sheathing requires at most one call. weaponController.SheathWeapon(fromRight, toAnimatorWeapon, dualSheath); } else { if (sheathLeft) { // Debug.Log("Sheath Left: " + fromLeft + " > " + toLeft); weaponController.SheathWeapon(fromLeft, toAnimatorWeapon, dualSheath); } if (sheathRight) { // Debug.Log("Sheath Right (dual: " + dualSheath + "): " + fromRight + " > " + toRight); weaponController.SheathWeapon(fromRight, toAnimatorWeapon, dualSheath); } } // Finally, unsheath the desired weapons! if (dualUnsheath && (unsheathRight || unsheathLeft)) { // Dual unsheathing requires at most one call. weaponController.UnsheathWeapon(toRight, dualUnsheath); } else { if (unsheathLeft) { // Debug.Log("Unsheath Left: " + toLeft); weaponController.UnsheathWeapon(toLeft, dualUnsheath); } if (unsheathRight) { // Debug.Log("Unsheath Right (dual: " + dualUnsheath + "): " + toRight); weaponController.UnsheathWeapon(toRight, dualUnsheath); } } } // This callback will update the weapons in character controller after all other // coroutines finish. weaponController.AddCallback(() => { if (changeLeft) { controller.leftWeapon = toLeft; } if (changeRight) { controller.rightWeapon = toRight; } // Turn off the isWeaponSwitching flag and sync weapon object visibility. weaponController.SyncWeaponVisibility(); controller.EndAction("Relax"); EndAction(controller); }); }