サイコロを回転させて地面に落ちた値を取得します。
13968 ワード
新しいスクリプト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