骰子旋转并获得落地后的值

 

新建一个脚本Die

/**
 * Copyright (c) 2010-2015, WyrmTale Games and Game Components
 * All rights reserved.
 * http://www.wyrmtale.com
 *
 * THIS SOFTWARE IS PROVIDED BY WYRMTALE GAMES AND GAME COMPONENTS 'AS IS' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL WYRMTALE GAMES AND GAME COMPONENTS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */  
using UnityEngine;
using System.Collections;

/// 
/// Die base class to determine if a die is rolling and to calculate it's current value
/// 
public class Die : MonoBehaviour {

	//------------------------------------------------------------------------------------------------------------------------------
	// public attributes
	//------------------------------------------------------------------------------------------------------------------------------
	
	// current value, 0 is undetermined (die is rolling) or invalid.
	public int value = 0;	

	//------------------------------------------------------------------------------------------------------------------------------
	// protected and private attributes
	//------------------------------------------------------------------------------------------------------------------------------	
	
	// normalized (hit)vector from die center to upper side in local space is used to determine what side of a specific die is up/down = value
    protected Vector3 localHitNormalized;
	// hitVector check margin
    protected float validMargin = 0.45F;

	// true is die is still rolling
    public bool rolling
    {
        get
        {
            return !(GetComponent().velocity.sqrMagnitude < .1F && GetComponent().angularVelocity.sqrMagnitude < .1F);
        }
    }

	// calculate the normalized hit vector and should always return true
    protected bool localHit
    {
        get
        {
			// create a Ray from straight above this Die , moving downwards
            Ray ray = new Ray(transform.position + (new Vector3(0, 2, 0) * transform.localScale.magnitude), Vector3.up * -1);
            RaycastHit hit = new RaycastHit();
			// cast the ray and validate it against this die's collider
            if (GetComponent().Raycast(ray, out hit, 3 * transform.localScale.magnitude))
            {
				// we got a hit so we determine the local normalized vector from the die center to the face that was hit.
				// because we are using local space, each die side will have its own local hit vector coordinates that will always be the same.
                localHitNormalized = transform.InverseTransformPoint(hit.point.x, hit.point.y, hit.point.z).normalized;
                return true;
            }
			// in theory we should not get at this position!
            return false;
        }
    }

	// calculate this die's value
    void GetValue()
    {
		// value = 0 -> undetermined or invalid
        value = 0;
        float delta = 1;
		// start with side 1 going up.
        int side = 1;
        Vector3 testHitVector;
		// check all sides of this die, the side that has a valid hitVector and smallest x,y,z delta (if more sides are valid) will be the closest and this die's value
        do
        {
			// get testHitVector from current side, HitVector is a overriden method in the dieType specific Die subclass
			// eacht dieType subclass will expose all hitVectors for its sides,
            testHitVector = HitVector(side);
            if (testHitVector != Vector3.zero)
            {
				// this side has a hitVector so validate the x,y and z value against the local normalized hitVector using the margin.
                if (valid(localHitNormalized.x, testHitVector.x) &&
                    valid(localHitNormalized.y, testHitVector.y) &&
                    valid(localHitNormalized.z, testHitVector.z))
                {
					// this side is valid within the margin, check the x,y, and z delta to see if we can set this side as this die's value
					// if more than one side is within the margin (especially with d10, d12, d20 ) we have to use the closest as the right side
                    float nDelta = Mathf.Abs(localHitNormalized.x - testHitVector.x) + Mathf.Abs(localHitNormalized.y - testHitVector.y) + Mathf.Abs(localHitNormalized.z - testHitVector.z);
                    if (nDelta < delta)
                    {
                        value = side;
                        delta = nDelta;
                    }
                }
            }
			// increment side
            side++;
			// if we got a Vector.zero as the testHitVector we have checked all sides of this die
        } while (testHitVector != Vector3.zero);
    }

    void Update()
    {
		// determine the value is the die is not rolling
        if (!rolling && localHit)
            GetValue();
    }


	// validate a test value against a value within a specific margin.
    protected bool valid(float t, float v)
    {
        if (t > (v - validMargin) && t < (v + validMargin))
            return true;
        else
            return false;
    }

	// virtual  method that to get a die side hitVector.
	// this has to be overridden in the dieType specific subclass
    protected virtual Vector3 HitVector(int side)
    {
        return Vector3.zero;
    }
	
}

 

新建一个Die_6脚本使它继承自Die脚本

 

 1 /**
 2  * Copyright (c) 2010-2015, WyrmTale Games and Game Components
 3  * All rights reserved.
 4  * http://www.wyrmtale.com
 5  *
 6  * THIS SOFTWARE IS PROVIDED BY WYRMTALE GAMES AND GAME COMPONENTS 'AS IS' AND ANY
 7  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 8  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 9  * DISCLAIMED. IN NO EVENT SHALL WYRMTALE GAMES AND GAME COMPONENTS BE LIABLE FOR ANY
10  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
14  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
15  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16  */ 
17 using UnityEngine;
18 using System.Collections;
19 
20 // Die subclass to expose the D6 side hitVectors
21 public class Die_d6 : Die
22 {
23     public Rigidbody rigidbody;
24    
25   
26     void Start()
27     {
28        
29         rigidbody = GetComponent();
30         rigidbody.angularVelocity = new Vector3(Random.value, Random.value, Random.value) *Time.deltaTime*Random.Range(100,1000);
31     }
32     override protected Vector3 HitVector(int side)
33     {
34         switch (side)
35         {
36             case 1: return new Vector3(0F, 0F, 1F);
37                 print("1");
38             case 2: return new Vector3(0F, -1F, 0F);
39                 print("1");
40             case 3: return new Vector3(-1F, 0F, 0F);
41                 print("1");
42             case 4: return new Vector3(1F, 0F, 0F);
43                 print("1");
44             case 5: return new Vector3(0F, 1F, 0F);
45                 print("1");
46             case 6: return new Vector3(0F, 0F, -1F);
47                 print("1");
48         }
49         return Vector3.zero;
50         
51     }
52 
53         
54 }

 

转载于:https://www.cnblogs.com/fuperfun/p/5466572.html

你可能感兴趣的:(骰子旋转并获得落地后的值)