/// <summary> /// Determines what kind of grapple is taking place. /// </summary> /// <param name="grappler"></param> /// <param name="victim"></param> /// <returns></returns> public static GrappleType ResolveGrappleType(Pawn grappler, Pawn victim) { GrappleType grappleType = GrappleType.None; if (grappler.RaceProps.Humanlike && victim.RaceProps.Humanlike) { grappleType = GrappleType.Humanoid; } else if (grappler.RaceProps.Humanlike && victim.RaceProps.Animal) { grappleType = GrappleType.HumanoidXAnimal; } else if (grappler.RaceProps.Animal && victim.RaceProps.Humanlike) { grappleType = GrappleType.AnimalXHumanoid; } else { grappleType = GrappleType.AnimalXAnimal; } return(grappleType); }
/// <summary> /// Sets up modifiers for grapple checks, similar to tabletop RPGs. /// If the characters are humanoid, use their melee skill in the check. /// </summary> /// <param name="grappler"></param> /// <param name="victim"></param> /// <param name="modifierGrappler"></param> /// <param name="modifierVictim"></param> public static void ResolveModifiers(Pawn grappler, Pawn victim, ref float modifierGrappler, ref float modifierVictim) { GrappleType grappleType = ResolveGrappleType(grappler, victim); switch (grappleType) { case GrappleType.Humanoid: modifierGrappler += grappler.skills.GetSkill(SkillDefOf.Melee).Level + ResolveToolModifier(grappler) + ResolveAdditionalModifiers(grappler); modifierVictim += victim.skills.GetSkill(SkillDefOf.Melee).Level + ResolveToolModifier(victim) + ResolveAdditionalModifiers(victim); break; case GrappleType.HumanoidXAnimal: modifierGrappler += grappler.skills.GetSkill(SkillDefOf.Melee).Level + ResolveToolModifier(grappler) + ResolveAdditionalModifiers(grappler); modifierVictim += ResolveToolModifier(victim); break; case GrappleType.AnimalXHumanoid: modifierGrappler += ResolveToolModifier(grappler); modifierVictim += victim.skills.GetSkill(SkillDefOf.Melee).Level + ResolveToolModifier(victim) + ResolveAdditionalModifiers(victim); break; case GrappleType.AnimalXAnimal: modifierGrappler += ResolveToolModifier(grappler); modifierVictim += ResolveToolModifier(victim); break; } }
void Update() { //Reset the last cached markerd object to it's original color if (mMarkedObject != null) { HighlightObject(mMarkedObject, GrappleOption.None); mMarkedObject = null; } Ray ray = Camera.main.ScreenPointToRay(mScreenCenter); if (Physics.Raycast(ray, out RaycastHit hit) && !mIsGrappling) { GameObject hitCollider = hit.collider.gameObject; GrappableObject grappleObject = hitCollider.GetComponent <GrappableObject>(); if (grappleObject) { mHandR_defaultRotation = mHandR.rotation; mHandL_defaultRotation = mHandL.rotation; //if the collided object is not grappable return //get landing zone for hit MeshFilter meshFilter = hitCollider.GetComponent <MeshFilter>(); Vector3 topCenter = hit.collider.bounds.center + hit.collider.bounds.extents.y * Vector3.up; var grapPosition = hit.point; Vector3 landingPosition = topCenter + Vector3.up * 0.15f; //If a pre defined landing position was specified make the one that was defined Vector3 predefinedLandingPoint = grappleObject.GetPredefinedLandingPoint(); if (predefinedLandingPoint != Vector3.zero) { landingPosition = predefinedLandingPoint; } //Calculate object distance to decide of grapple is possible float dist = Vector3.Distance(grapPosition, mPlayerBody.position); float y_diff = Mathf.Abs(landingPosition.y - transform.position.y); Debug.Log("y_diff: " + y_diff); Debug.Log("dist: " + dist); if (dist < GRAPPLE_RADIUS_LENGTH && y_diff < GRAPPLE_MAX_HEIGHT_DIFF && grappleObject.GetGrappleType() != GrappleType.None) { mMarkedObject = hitCollider; //Mark the object as grappable HighlightObject(mMarkedObject, GrappleOption.CanGrapple); //If left mouse button is pressed Initiate grapple if (Input.GetMouseButtonDown(0)) { mGrappleState = GrappleState.Shot; grappleObject.OnGrapped(); RotateHandToPoint(mHandR, grapPosition); RotateHandToPoint(mHandL, grapPosition); mHandL.DOScaleX(dist, .5f); mHandR.DOScaleX(dist, .5f).OnComplete(() => { mIsGrappling = true; mGrappleState = GrappleState.Attached; mAttachedPosition = topCenter; //Get grapping type GrappleType type = grappleObject.GetGrappleType(); //Handle different types of grapple switch (type) { case GrappleType.None: _handsTrigger.Trigger(); mHandL.DOScaleX(1, .5f); mHandR.DOScaleX(1, .5f).OnComplete(() => { FinishGrappling(); _handsTrigger.Stop(); }); break; case GrappleType.Heavy: //dotween to the wanted position ResetHandsScale(); _handsTrigger.Trigger(); mPlayerBody.DOMove(landingPosition, .5f).SetEase(Ease.OutQuad).OnComplete(() => { FinishGrappling(); _handsTrigger.Stop(); }); break; case GrappleType.Light: //Snap the object to the player ResetHandsScale(); var colliderTransform = hit.collider.gameObject.transform; var dest = mPlayerBody.position + mPlayerBody.forward * 2; _handsTrigger.Trigger(); colliderTransform.DOMove(new Vector3(dest.x, colliderTransform.position.y, dest.z), .5f) .OnComplete(() => { FinishGrappling(); _handsTrigger.Stop(); }); break; case GrappleType.VeryLight: //Snap the object to the player ResetHandsScale(); hit.collider.gameObject.GetComponent <Rigidbody>().velocity = UnityEngine.Random.onUnitSphere * 20; FinishGrappling(); break; case GrappleType.Special: Animator anim = hitCollider.GetComponent <Animator>(); if (!anim) { throw new Exception("Special object should always have animators"); } anim.SetTrigger("Hit"); _handsTrigger.Trigger(); mHandL.DOScaleX(1, .5f); mHandR.DOScaleX(1, .5f).OnComplete(() => { FinishGrappling(); _handsTrigger.Stop(); }); break; } }); } } else { //If the object is too far away we would like to mark it as red mMarkedObject = hit.collider.gameObject; //Mark the object as grappable HighlightObject(mMarkedObject, GrappleOption.CannotGrapple); } } } }
public void SetType(GrappleType type) { mGrappleType = type; }